Fix bug in Flatten lisp when deal with text objects

Fix bug in Flatten lisp when deal with text objects

hanywillim
Enthusiast Enthusiast
1,205 Views
15 Replies
Message 1 of 16

Fix bug in Flatten lisp when deal with text objects

hanywillim
Enthusiast
Enthusiast

Hi my friends,
i am using this lisp to flat all lines in the cad drawings but i found in some cad files it moves the text away from its place and that is not the desired act.

(defun flatall ( / a n ss)
;  (vl-load-com)
  ; flatten objects inside blocks
   (vlax-for b (vla-get-blocks (setq a (vla-get-activedocument (vlax-get-acad-object)))) ; select all blocks
       (if (= :vlax-false (vla-get-isxref b)) ; ignore xref blocks
           (vlax-for o b
               (if (vlax-write-enabled-p o) ; chk if object can be moved
                   (foreach e '(1e99 -1e99)
                       (vlax-invoke o 'move '(0.0 0.0 0.0) (list 0.0 0.0 e))    ; flatten to 1e99 -1e99 which = 0 elevation 
                   ) ; foreach
               ) ; if
           ) ; vlax-for
       ) ; if
   ) ; vlax-for
  ; flatten objects outside blocks
   (if(setq ss (ssget"_X")) ; select all objects
     (progn     
      (setq ss (mapcar 'vlax-ename->vla-object (mapcar 'cadr (ssnamex ss)))) ; cnvert to list of entities then to vl obj
      (foreach i (list 1e99 -1e99) 
       (mapcar(function(lambda (x) (vla-move x (vlax-3d-point (list 0 0 0)) (vlax-3d-point (list 0 0 i))))) ss)    ; flatten to 1e99 -1e99 which = 0 elevation 
      ) ; foreach
     ) ; progn
   ) ; if ss
   (vla-regen a acallviewports) ; regen 
   (princ)
) ; defun flatall

 

i will attach the drawings which all the texts moved away by so far from its places with no reason.

 

May anyone explain why that happened and how to modify the code to avoid this kind or error?

0 Likes
1,206 Views
15 Replies
Replies (15)
Message 2 of 16

Sea-Haven
Mentor
Mentor

What does the inbuilt Flatten do ?

0 Likes
Message 3 of 16

john.uhden
Mentor
Mentor

@Sea-Haven ,

"inbuilt?"  You have reminded me of the old BC comic strip.

BC and his buddy encounter a new species with a long snout they had never seen before.  BC says, "Maybe we're the first.  We have to name this thing.  What does he do?"  His buddy responds, "Looks like all he does is eat ants."  BC says, "That's it!  He must be an Eatanter!"

John F. Uhden

0 Likes
Message 4 of 16

ronjonp
Mentor
Mentor

@hanywillim wrote:

Hi my friends,
i am using this lisp to flat all lines in the cad drawings but i found in some cad files it moves the text away from its place and that is not the desired act.

(defun flatall ( / a n ss)
;  (vl-load-com)
  ; flatten objects inside blocks
   (vlax-for b (vla-get-blocks (setq a (vla-get-activedocument (vlax-get-acad-object)))) ; select all blocks
       (if (= :vlax-false (vla-get-isxref b)) ; ignore xref blocks
           (vlax-for o b
               (if (vlax-write-enabled-p o) ; chk if object can be moved
                   (foreach e '(1e99 -1e99)
                       (vlax-invoke o 'move '(0.0 0.0 0.0) (list 0.0 0.0 e))    ; flatten to 1e99 -1e99 which = 0 elevation 
                   ) ; foreach
               ) ; if
           ) ; vlax-for
       ) ; if
   ) ; vlax-for
  ; flatten objects outside blocks
   (if(setq ss (ssget"_X")) ; select all objects
     (progn     
      (setq ss (mapcar 'vlax-ename->vla-object (mapcar 'cadr (ssnamex ss)))) ; cnvert to list of entities then to vl obj
      (foreach i (list 1e99 -1e99) 
       (mapcar(function(lambda (x) (vla-move x (vlax-3d-point (list 0 0 0)) (vlax-3d-point (list 0 0 i))))) ss)    ; flatten to 1e99 -1e99 which = 0 elevation 
      ) ; foreach
     ) ; progn
   ) ; if ss
   (vla-regen a acallviewports) ; regen 
   (princ)
) ; defun flatall

 

i will attach the drawings which all the texts moved away by so far from its places with no reason.

 

May anyone explain why that happened and how to modify the code to avoid this kind or error?


You don't need any of this code in red:

image.png

0 Likes
Message 5 of 16

hanywillim
Enthusiast
Enthusiast

No, i still need the code to flatten all lines if they are outside the blocks or inside them.

My question is how to prevent moveing text objects in x and y coordinates and only flatten them in z direction.

0 Likes
Message 6 of 16

hanywillim
Enthusiast
Enthusiast

Is there any one understand why the text moved to 0,0,0 point in the attached drawing?

0 Likes
Message 7 of 16

CADaSchtroumpf
Advisor
Advisor

For your text, does this solve your problem?

(defun c:foo ( / ss n ent dxf_ent dxf_210 dxf_10 dxf_11)
  (setq ss (ssget '((0 . "TEXT"))))
  (repeat (setq n (sslength ss))
    (setq
      ent (ssname ss (setq n (1- n)))
      dxf_ent (entget ent)
      dxf_210 (cdr (assoc 210 dxf_ent))
      dxf_10 (trans (cdr (assoc 10 dxf_ent)) dxf_210 0)
      dxf_11 (trans (cdr (assoc 11 dxf_ent)) dxf_210 0)
      dxf_ent (subst (cons 10 (list (car dxf_10) (cadr dxf_10) 0.0)) (assoc 10 dxf_ent) dxf_ent)
      dxf_ent (subst (cons 11 (list (car dxf_11) (cadr dxf_11) 0.0)) (assoc 11 dxf_ent) dxf_ent)
      dxf_ent (subst '(210 0.0 0.0 1.0) (assoc 210 dxf_ent) dxf_ent)
    )
    (entmod dxf_ent)
  )
  (prin1)
)
0 Likes
Message 8 of 16

hanywillim
Enthusiast
Enthusiast

how to merge this code inside my main lisp for flatten and prevent the previous  error to happen agian

0 Likes
Message 9 of 16

CADaSchtroumpf
Advisor
Advisor

Only tested with your drawing (be carrefull)

(defun flatall ( / a n ss n ent dxf_ent dxf_210 dxf_10 dxf_11)
  (vl-load-com)
  ; flatten objects inside blocks
   (vlax-for b (vla-get-blocks (setq a (vla-get-activedocument (vlax-get-acad-object)))) ; select all blocks
       (if (= :vlax-false (vla-get-isxref b)) ; ignore xref blocks
           (vlax-for o b
               (if (and (vlax-write-enabled-p o) (not (member (vlax-get o 'ObjectName) '("AcDbText" "AcDbMText")))) ; chk if object can be moved
                   (foreach e '(1e99 -1e99)
                       (vlax-invoke o 'move '(0.0 0.0 0.0) (list 0.0 0.0 e))    ; flatten to 1e99 -1e99 which = 0 elevation 
                   ) ; foreach
               ) ; if
           ) ; vlax-for
       ) ; if
   ) ; vlax-for
   (vla-regen a acallviewports) ; regen 
  (setq ss (ssget "_X" '((0 . "TEXT"))))
  (repeat (setq n (sslength ss))
    (setq
      ent (ssname ss (setq n (1- n)))
      dxf_ent (entget ent)
      dxf_210 (cdr (assoc 210 dxf_ent))
      dxf_10 (trans (cdr (assoc 10 dxf_ent)) dxf_210 0)
      dxf_11 (trans (cdr (assoc 11 dxf_ent)) dxf_210 0)
      dxf_ent (subst (cons 10 (list (car dxf_10) (cadr dxf_10) 0.0)) (assoc 10 dxf_ent) dxf_ent)
      dxf_ent (subst (cons 11 (list (car dxf_11) (cadr dxf_11) 0.0)) (assoc 11 dxf_ent) dxf_ent)
      dxf_ent (subst '(210 0.0 0.0 1.0) (assoc 210 dxf_ent) dxf_ent)
    )
    (entmod dxf_ent)
  )
   (princ)
) ; defun flatall
0 Likes
Message 10 of 16

hanywillim
Enthusiast
Enthusiast

i still need the part to flatten lines outside the blocks i can not find it in the code

0 Likes
Message 11 of 16

ronjonp
Mentor
Mentor

@hanywillim wrote:

No, i still need the code to flatten all lines if they are outside the blocks or inside them.

My question is how to prevent moveing text objects in x and y coordinates and only flatten them in z direction.


@hanywillim 

This portion of the code processes block definitions as well as layouts so the code below it is redundant. Did you know that a layout is a 'block'? Try this: (tblobjname "block" "*Model_Space")

 

  ; flatten objects inside blocks
   (vlax-for b (vla-get-blocks (setq a (vla-get-activedocument (vlax-get-acad-object)))) ; select all blocks
       (if (= :vlax-false (vla-get-isxref b)) ; ignore xref blocks
           (vlax-for o b
               (if (vlax-write-enabled-p o) ; chk if object can be moved
                   (foreach e '(1e99 -1e99)
                       (vlax-invoke o 'move '(0.0 0.0 0.0) (list 0.0 0.0 e))    ; flatten to 1e99 -1e99 which = 0 elevation 
                   ) ; foreach
               ) ; if
           ) ; vlax-for
       ) ; if
   ) ; vlax-for

 

 

0 Likes
Message 12 of 16

john.uhden
Mentor
Mentor

@hanywillim ,

I tried my SQUASH on all your entities, and the cyan text didn't cooperate fully.  I found it was because of its normal (210 -0.000372211 0.0017426 0.999998).  I don't know if that was intended, but as soon as I modified it to (0.0 0.0 1.0) its Z became zero and its X,Y hadn't changed (at least as far as I could tell).

So, should my SQUASH set every normal to normal (WCS), or should it just warn the user of non-world normals?

John F. Uhden

0 Likes
Message 13 of 16

hanywillim
Enthusiast
Enthusiast

So, Can you provide me with the full correct code to handle this, Please?

0 Likes
Message 14 of 16

john.uhden
Mentor
Mentor

@hanywillim ,

So, do you think I should add the automatic Normal correction, or just a warning?

John F. Uhden

0 Likes
Message 15 of 16

ronjonp
Mentor
Mentor

@hanywillim This should do it.

(defun c:flatall (/ a n ss)
  (vlax-for b (vla-get-blocks (setq a (vla-get-activedocument (vlax-get-acad-object))))
    (if	(= :vlax-false (vla-get-isxref b))
      (vlax-for	o b
	(if (vlax-write-enabled-p o)
	  (progn (vl-catch-all-apply 'vlax-put (list o 'normal '(0.0 0.0 1.0)))
		 (foreach e '(1e99 -1e99) (vlax-invoke o 'move '(0.0 0.0 0.0) (list 0.0 0.0 e)))
	  )
	)
      )
    )
  )
  (vla-regen a acallviewports)
  (princ)
)

 

0 Likes
Message 16 of 16

john.uhden
Mentor
Mentor

@hanywillim 

You didn't answer so I included automated correction of each entity's normal.

 

John F. Uhden

0 Likes