Jump to content

Custom transformation and entity types


aps
 Share

Recommended Posts

Hi!

 

First of all sorry for my poor english. I'm total beginner in AutoLISP, I work mostly with GIS software and data, but i have to manage the following problem. I've recieved a big DWG file which is containing around 30000 entities with various entity types and several layers. Everything is in a custom local coordinate system, and I have to transform it into an other coordinate system. I only have the transformation equations, so I create my first AutoLISP file based on codes I've found on this and other forums:

 

(defun c:customtransform()
 (if (setq ss (ssget "_:L"))
   (repeat (setq i (sslength ss))
       (setq entitylist (entget (ssname ss (setq i (1- i)))))
       (setq obj (ssname ss i))
       (setq new nil)
       (repeat (setq j (length entitylist))
           (if (= 10 (car (nth (setq j (1- j)) entitylist)))
               (progn
                   (setq x (cadr (nth j entitylist))
                   y (caddr (nth j entitylist))
                   )
                   (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
                   (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
                   (setq new (cons (list 10 x y) new))
               )
               (setq new (cons (nth j entitylist) new))
           )
       )
       (entdel obj)
       (entmake new)
   )
 )
 (princ)
)

It mostly does what I want, but there are 3 problems:

 

1. It does not move objects with MLINE and REGION entity type.

 

2. It transforms only a part of the LINE and 3D FACE entities. For example: one node of a LINE entity moves into the new position and the other node remains in the original position, so the result is a long line, with one node in the correct position and one node in the old position.

 

3. It works perfectly with most of the TEXT entities, but there are some TEXTs that remain in their original positions, and I can't find out what is the difference between the "working" texts and the "non-working" texts.

 

Any advice how to fix the problems mentioned above?

Thanks for any help!

Link to comment
Share on other sites

For MLINE ???, REGION and 3D SOLID entities I can't help, but I suppose that for all other types this fix can do...

 

(defun c:customtransform ( / ss i entitylist obj new j x y )
 (if (setq ss (ssget "_:L"))
   (repeat (setq i (sslength ss))
     (setq entitylist (entget (ssname ss (setq i (1- i)))))
     (setq obj (ssname ss i))
     (setq new nil)
     (repeat (setq j (length entitylist))
       (cond 
         ( (= 10 (car (nth (setq j (1- j)) entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 10 x y) new))
         )
         ( (= 11 (car (nth j entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 11 x y) new))
         )
         ( (= 12 (car (nth j entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 12 x y) new))
         )
         ( (= 13 (car (nth j entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 13 x y) new))
         )
         ( (= 14 (car (nth j entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 14 x y) new))
         )
         ( (= 15 (car (nth j entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 15 x y) new))
         )
         ( (= 16 (car (nth j entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 16 x y) new))
         )
         ( t
           (setq new (cons (nth j entitylist) new))
         )
       )
     )
     (entdel obj)
     (entmake new)
   )
 )
 (princ)
)

HTH, M.R.

Edited by marko_ribar
code changed
Link to comment
Share on other sites

Maybe try this, Insert dwg into a another as a block you can adjust the x & y scale 0.40008 0.595 etc then do a move press F8 ortho on drag mouse enter 3321434 then again for y 1087 then explode block and purge to remove the BLock definition from within the dwg.

Link to comment
Share on other sites

For MLINE ???, REGION and 3D SOLID entities I can't help, but I suppose that for all other types this fix can do...

 

(defun c:customtransform ( / ss i entitylist obj new j x y )
 (if (setq ss (ssget "_:L"))
   (repeat (setq i (sslength ss))
     (setq entitylist (entget (ssname ss (setq i (1- i)))))
     (setq obj (ssname ss i))
     (setq new nil)
     (repeat (setq j (length entitylist))
       (cond 
         ( (= 10 (car (nth (setq j (1- j)) entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 10 x y) new))
         )
         ( (= 11 (car (nth (setq j (1- j)) entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 11 x y) new))
         )
         ( (= 12 (car (nth (setq j (1- j)) entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 12 x y) new))
         )
         ( (= 13 (car (nth (setq j (1- j)) entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 13 x y) new))
         )
         ( (= 14 (car (nth (setq j (1- j)) entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 14 x y) new))
         )
         ( (= 15 (car (nth (setq j (1- j)) entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 15 x y) new))
         )
         ( (= 16 (car (nth (setq j (1- j)) entitylist)))
           (setq x (cadr (nth j entitylist))
                 y (caddr (nth j entitylist))
           )
           (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
           (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
           (setq new (cons (list 16 x y) new))
         )
         ( t
           (setq new (cons (nth j entitylist) new))
         )
       )
     )
     (entdel obj)
     (entmake new)
   )
 )
 (princ)
)

 

HTH, M.R.

 

 

Thank you, but I've got an error message when I try to run it:

 

error: bad argument value: non-negative: -1

 

What does it mean?

 

With only the first condition and the else condition it works like before:

(defun c:customtransform ()
  (if (setq ss (ssget "_:L"))
    (repeat (setq i (sslength ss))
      (setq entitylist (entget (ssname ss (setq i (1- i)))))
      (setq obj (ssname ss i))
      (setq new nil)
      (repeat (setq j (length entitylist))
        (cond 
          ( (= 10 (car (nth (setq j (1- j)) entitylist)))
            (setq x (cadr (nth j entitylist))
                  y (caddr (nth j entitylist))
            )
            (setq y (+ (+ (+ 0 332134.109) (* 0.40008331 x)) (* 0.59595102 y)))
            (setq x (+ (+ (+ 0 1087.012) (* 0.59595102 x)) (* -0.40008331 y)))
            (setq new (cons (list 10 x y) new))
          )
          
          ( t
            (setq new (cons (nth j entitylist) new))
          )
        )
      )
      (entdel obj)
      (entmake new)
    )
  )
 
)

 

But if I add the second or any other condition the error message apears.

Link to comment
Share on other sites

That's because I didn't test it... I've updated fix, should work now as expected, but I think BIGAL's suggestion is what I should do... Of course apply code on block of entire DWG, explode and purge that block...

 

M.R.

Link to comment
Share on other sites

Maybe try this, Insert dwg into a another as a block you can adjust the x & y scale 0.40008 0.595 etc then do a move press F8 ortho on drag mouse enter 3321434 then again for y 1087 then explode block and purge to remove the BLock definition from within the dwg.

 

Thank you for the idea, but more DWGs with such content will arrive soon, and I want to provide a foolproof tool to my colleagues.

Link to comment
Share on other sites

That's because I didn't test it... I've updated fix, should work now as expected, but I think BIGAL's suggestion is what I should do... Of course apply code on block of entire DWG, explode and purge that block...

 

M.R.

 

Can you show me the updated version of the code?

 

Thank you!

Link to comment
Share on other sites

2 things if the scale and move are different for each then you will need to change Marko's code to allow for user input of these values.

 

Back to mine you could ask the questions about the scale and move and automate using the insert method as well. Just open new dwg and run a lisp.

Link to comment
Share on other sites

Hi, I'm back with my problem. Thank you Marco and BIGAL for your help!

Marko's code works fine, except for ellipses and regions. Therefore I took into consideration the block idea. I extended the LISP file with Lee Mac's Polyline to Block code, so now it converts all object into a single block and then transform it into the new coordinate system. I was happy because after exploding the transformed block I got exactly what I want, but during data verification I found that this method results inaccurate coordinates.

 

I checked with manual calculations that Marko's transform-only code is deadly accurate. But when I convert the objects into a single block (either with Lee Mac's method or with hand in AutoCAD) and then run the transformation routine on the block, inaccuracy occurs. The degree of inaccuracy seems to be constant and it is between 10 and 100 cm (4-39"), depends on the basepoint of the block selected before the transformation.

Why does this inaccuracy occur? How can I get rid of it?

Link to comment
Share on other sites

I made some measurements: transforming directly a single circle (diameter = 3 cm) with Marko's good code and transforming after converted to a block results around 6 mm (1/4") difference. With a polyline the difference is bigger. Converting to block and transforming more than 1 object the error is increasing. I observed that using (0,0) as the block's base point gives the biggest error, while using EXTMIN as the base point results lower error. I've got the smallest difference when I use the center of the extent (EXTMAX - EXTMIN / 2) as the base point, it's around 4 - 7 cm, but it's interesting that the error is not constant, when I use the center of the extent as the base point, I've got bigger errors close to EXTMIN and smaller errors close to EXTMAX.

Unfortunately I don't know anything about AutoCAD's block handling, so I can't find out how to elliminate the error generated by converting the objects into a block before transformation. Do you have any ideas?

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...