Need help with LISP code Hatch Creation

Need help with LISP code Hatch Creation

Hannan1
Advocate Advocate
1,315 Views
20 Replies
Message 1 of 21

Need help with LISP code Hatch Creation

Hannan1
Advocate
Advocate

Hello everyone,

I need help with the code to create rectangle hatch with associated polyline and it should be place it with "inspt" of hatch origin point, I'm trying to access Origin point unfortunately exactly DXF code is not there, how we can place it in the center of rectangle.

 

(defun c:RectHatch ()
  (prompt "\nRectangle with Hatch and Associated Boundary\n")

  (setq len (getreal "\nEnter the length of the rectangle: "))
  (setq wid (getreal "\nEnter the width of the rectangle: "))

  (setq inspt (getpoint "\nSpecify the insertion point: "))

  (setq pt1 inspt)
  (setq pt2 (polar pt1 0 len))       
  (setq pt3 (polar pt2 (/ pi 2) wid)) 
  (setq pt4 (polar pt1 (/ pi 2) wid)) 

  (setq pl (entmakex
    (list
      '(0 . "LWPOLYLINE")
      '(100 . "AcDbEntity")
      '(100 . "AcDbPolyline")
      (cons 90 4)
      '(70 . 1)
      (cons 10 pt1)
      (cons 10 pt2)
      (cons 10 pt3)
      (cons 10 pt4)
    )
  ))

  (if pl
    (progn
      (setq hatch (entmakex
        (list
          '(0 . "HATCH")
          '(100 . "AcDbEntity")
          '(100 . "AcDbHatch")
          '(cons 10 inspt)
          '(70 . 1)
          '(71 . 0)
          '(75 . 1)
          '(76 . 1)
          '(45 . 0.0)
          '(2 . "ANSI31")
          '(91 . 1)
          (list
            '(92 . 2)
            (cons -1 pl)
          )
        )
      ))

      (if hatch
        (progn
          (redraw pl 3)
          (redraw hatch 3)
          (princ "\nRectangle with Hatch created successfully.")
        )
        (princ "\nError: Failed to create hatch.")
      )
    )
    (princ "\nError: Failed to create polyline.")
  )
  (princ)
)

 

0 Likes
Accepted solutions (4)
1,316 Views
20 Replies
Replies (20)
Message 2 of 21

Kent1Cooper
Consultant
Consultant

@Hannan1 wrote:

.... place it with "inspt" of hatch origin point, I'm trying to access Origin point unfortunately exactly DXF code is not there....


The origin point is held in Extended Data, not just the regular entity data.  This will show you the Extended Data:

(cadr (assoc -3 (entget TheHatchEntityName '("ACAD"))))

which for a Hatch pattern, looks something like this:

("ACAD" (1010 18.5668 7.57394 0.0))

The numbers following the 1010 are the XYZ coordinates of the origin point.

I've been trying to find the way to substitute a different origin point into that, so far without success.  But maybe someone out there knows how to inject different values into Extended Data.  Or, I've been trying on an existing Hatch pattern by substitution, but maybe it's easier within (entmakex)ing it.

Kent Cooper, AIA
Message 3 of 21

paullimapa
Mentor
Mentor

Or you can always use the command line versions to change the already generated hatch

This example uses command hatchsetorigin 

https://www.cadtutor.net/forum/topic/59025-hatch-creation-and-set-origin-lisp/

This example uses command Hatchedit 

https://www.cadtutor.net/forum/topic/78376-hatch-origin-change-not-working/


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 4 of 21

Hannan1
Advocate
Advocate

@Kent1Cooper Thanks for the Extended Data DXF code, I found another way to get Geometric Center point to place rectangle, But the problem is hatch does not create inside closed polyline.

 

(defun c:RectHatch ()
  (prompt "\nRectangle with Hatch and Associated Boundary\n")
  (setq len (getreal "\nEnter the length of the rectangle: "))
  (setq wid (getreal "\nEnter the width of the rectangle: "))
  (setq center (getpoint "\nSpecify the center point of the rectangle: "))
  (setq half-len (/ len 2))
  (setq half-wid (/ wid 2))
  (setq pt1 (list (- (car center) half-len) (- (cadr center) half-wid) 0.0))
  (setq pt2 (list (+ (car center) half-len) (- (cadr center) half-wid) 0.0))
  (setq pt3 (list (+ (car center) half-len) (+ (cadr center) half-wid) 0.0))
  (setq pt4 (list (- (car center) half-len) (+ (cadr center) half-wid) 0.0))
  (setq pl (entmakex
    (list
      '(0 . "LWPOLYLINE")
      '(100 . "AcDbEntity")
      '(100 . "AcDbPolyline")
      (cons 90 4)
      '(70 . 1)
      (cons 10 pt1)
      (cons 10 pt2)
      (cons 10 pt3)
      (cons 10 pt4)
    )
  ))
  (if pl
    (progn
      (setq hatch (entmakex
        (list
          '(0 . "HATCH")
          '(100 . "AcDbEntity")
          '(100 . "AcDbHatch")
          '(10 0.0 0.0 0.0)
          '(70 . 1)
          '(71 . 0)
          '(75 . 1)
          '(76 . 1)
          '(45 . 0.0)
          '(2 . "ANSI31")
          '(91 . 1)
          '(92 . 2)
          '(72 . 1)
          '(73 . 1)
          '(93 . 4)
          (cons 10 pt1)
          (cons 10 pt2)
          (cons 10 pt3)
          (cons 10 pt4)
          (cons 10 pt1)
        )
      ))
      (if hatch
        (progn
          (redraw pl 3)
          (redraw hatch 3)
          (princ "\nRectangle with Hatch created successfully.")
        )
        (princ "\nError: Failed to create hatch.")
      )
    )
    (princ "\nError: Failed to create polyline.")
  )
  (princ)
)

 

0 Likes
Message 5 of 21

Kent1Cooper
Consultant
Consultant

@Hannan1 wrote:

.... the problem is hatch does not create inside closed polyline.


Does it not create it at all, or does it create it but somewhere else?  Are there any messages?  If it doesn't create it at all, maybe you're missing some essential entry -- look in the DXF Reference to see which are optional-with-default.

One thing I notice is that you have (cons 10) entries for vertices in the Hatch list with a repeat of the first one at the end.  Hatch patterns' entity data does not have that -- it would be just the four.

Another thing, which may not matter if your Polyline is being created successfully:  The 10 entries in Polyline entity data do not contain Z coordinates as yours do [that's set by the elevation property].  I was surprised to find that those for Hatches do, which implies that a Hatch should be able to be non-planar, but I haven't experimented.

Or, as already suggested, just use a HATCH command -- also much easier than (entmakex).  So is a RECTANG command for the rectangle [if it's orthogonal as in your case], because it needs only two opposite corners, not all four.  If you were specifying a Layer for either of them that might not be current, maybe that would suggest (entmakex), but you're not, so in either case the current Layer will be used [likewise for certain other properties].

Kent Cooper, AIA
0 Likes
Message 6 of 21

calderg1000
Mentor
Mentor

Saludos  @Hannan1 

Prueba a aplicar el hatch de una forma más sencilla con "comando"...

 

(defun c:rh (/pl)
  (prompt "\nRectangle with Hatch and Associated Boundary\n")
  (setq len (getreal "\nEnter the length of the rectangle: "))
  (setq wid (getreal "\nEnter the width of the rectangle: "))
  (setq center (getpoint "\nSpecify the center point of the rectangle: "))
  (setq half-len (/ len 2))
  (setq half-wid (/ wid 2))
  (setq pt1 (list (- (car center) half-len) (- (cadr center) half-wid) 0.0))
  (setq pt2 (list (+ (car center) half-len) (- (cadr center) half-wid) 0.0))
  (setq pt3 (list (+ (car center) half-len) (+ (cadr center) half-wid) 0.0))
  (setq pt4 (list (- (car center) half-len) (+ (cadr center) half-wid) 0.0))
  (setq pl (entmakex
    (list
      '(0 . "LWPOLYLINE")
      '(100 . "AcDbEntity")
      '(100 . "AcDbPolyline")
      (cons 90 4)
      '(70 . 1)
      (cons 10 pt1)
      (cons 10 pt2)
      (cons 10 pt3)
      (cons 10 pt4)
    )
  ))
  (if pl
    (command "_hatch" "" pl "") 
    (princ "\nError: Failed to create polyline.")
  )
  (princ)
)

 

 


Carlos Calderon G
EESignature
>Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

0 Likes
Message 7 of 21

Kent1Cooper
Consultant
Consultant
Accepted solution

@calderg1000 wrote:

Try applying the hatc in a simpler way with "command"...


If going with the (command) approach for the Hatch, it may as well be used for the rectangle, too.  And the Hatch command should have more in it.  And various things can be consolidated [more than one variable can be defined in a single (setq) function, and more than one command specified in a single (command) function].  And variables should be localized.  Lightly tested:

(defun C:RectHatch (/ len wid ctr half-len half-wid)
  (prompt "\nRectangle with Hatch and Associated Boundary\n")
  (setq
    len (getdist "\nHorizontal dimension of rectangle: ")
    wid (getdist "\nVertical dimension of rectangle: ")
    ctr (getpoint "\nCenter point of rectangle: ")
    half-len (/ len 2)
    half-wid (/ wid 2)
  ); setq
  (command
    "_.rectang"
      "_non" (mapcar '- ctr (list half-len half-wid))
      "_non" (mapcar '+ ctr (list half-len half-wid))
    "_.hatch" "ANSI31" 1 0 "_last" ""
  ); command
  (prin1)
)

Note the use of (getdist) for the length/width [which it prompts for in different and unambiguous terms], which allows you to pick on-screen, or to enter in whatever type of units you're using [such as feet-inches-fractions], not only in integer or decimal format.

Kent Cooper, AIA
0 Likes
Message 8 of 21

calderg1000
Mentor
Mentor
Accepted solution

Regards @Hannan1 

Here is another similar form...

 

 

;;;___
(defun c:rh (/)
  (prompt "\nRectangle with Hatch and Associated Boundary\n")
  (initget 7)
  (setq len (getreal "\nEnter the length of the rectangle: "))
  (initget 7)
  (setq
    wid    (getreal "\nEnter the width of the rectangle: ")
    center (getpoint "\nSpecify the center point of the rectangle: ")
    pv     (list (* len 0.5) (* wid 0.5))
    pt2    (mapcar '(lambda (u v) (+ u v)) center pv)
    pt1    (mapcar '(lambda (u v) (- u v)) center pv)
  )
  (command "_rectangle" "_non" pt1 "_non" pt2)
  (command "_hatch" "ANSI32" "1" "0" (entlast) "")
  (princ)
)

 

 


Carlos Calderon G
EESignature
>Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

0 Likes
Message 9 of 21

komondormrex
Mentor
Mentor
Accepted solution

@Hannan1 

hey there,

check the following. rectangle is drawn using rectang command, hatch using activex.

 

(defun c:rect_hatch (/ len wid ins_point rectangle hatch_object)
  	(setq len (getreal "\nEnter the length of the rectangle: ")
  	      wid (getreal "\nEnter the width of the rectangle: ")
	)
	(command "_.rectang" "_non" (setq ins_point (getpoint "\nSpecify the insertion point: ")) "_d" len wid "_non" (mapcar '+ (list len wid) ins_point))
	(setq rectangle (vlax-ename->vla-object (entlast))) 
	(setq hatch_object (vla-addhatch (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
									 achatchpatterntypepredefined
									 "ANSI31"
									 :vlax-true
									 achatchobject
					   )
	)
	(vlax-safearray-put-element (setq outer_loop (vlax-make-safearray vlax-vbobject '(0 . 0))) 0 rectangle)
	(vla-appendouterloop hatch_object outer_loop)
  	(vlax-put hatch_object 'origin (mapcar '+ (mapcar '* '(0.5 0.5) (list len wid)) ins_point))
  	(princ "\nRectangle with Hatch created successfully.")
	(princ)
)

 

0 Likes
Message 10 of 21

Hannan1
Advocate
Advocate

Sorry for late reply, Thanks @komondormrex @calderg1000 @Kent1Cooper @paullimapa 

Your codes looks well-written and functional, and I can see why it’s working as expected!

It's using a combination of vla functions for creating and associating the hatch with the rectangle, which is a robust approach.

Here's I have added another ability see below code.

Check there is some error at the end.

 

 

(defun c:RectHatch (/ len wid center pv pt1 pt2 source_hatch pattern scale rotation layer_name hatch_object outer_loop rectangle)
  (prompt "\nRectangle with Hatch and Associated Boundary\n")
  (initget 7)
  (setq len (getreal "\nEnter the length of the rectangle: "))
  (initget 7)
  (setq wid (getreal "\nEnter the width of the rectangle: "))
  (setq center (getpoint "\nSpecify the center point of the rectangle: "))

  (setq source_hatch (car (entsel "\nSelect an existing hatch to match properties: ")))

  (if (and source_hatch (eq (cdr (assoc 0 (entget source_hatch))) "HATCH"))
    (progn
      (setq vla-source-hatch (vlax-ename->vla-object source_hatch))
      (setq pattern (vlax-get vla-source-hatch 'PatternName))
      (setq scale (vlax-get vla-source-hatch 'PatternScale))
      (setq rotation (vlax-get vla-source-hatch 'PatternAngle))
      (setq is_double (vlax-get vla-source-hatch 'PatternDouble))
      (setq layer_name (vlax-get vla-source-hatch 'Layer))

      (setq pv  (list (* len 0.5) (* wid 0.5))
            pt2 (mapcar '(lambda (u v) (+ u v)) center pv)
            pt1 (mapcar '(lambda (u v) (- u v)) center pv))

      (command "_rectangle" "_non" pt1 "_non" pt2)
      (setq rectangle (vlax-ename->vla-object (entlast)))

      (setq hatch_object (vla-addhatch
                           (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
                           achatchpatterntypepredefined
                           pattern
                           :vlax-true
                           achatchobject))

      (setq outer_loop (vlax-make-safearray vlax-vbobject '(0 . 0)))
      (vlax-safearray-put-element outer_loop 0 rectangle)
      (vla-appendouterloop hatch_object outer_loop)

      (vlax-put hatch_object 'PatternScale scale)
      (vlax-put hatch_object 'PatternAngle rotation)
      (vlax-put hatch_object 'PatternDouble is_double)
      (vlax-put hatch_object 'Layer layer_name)

      (vlax-put hatch_object 'origin center)

      (vla-update hatch_object)

      (princ (strcat "\nRectangle with Hatch created successfully on layer: " layer_name))
    )
    (princ "\nError: Please select a valid hatch to match properties.")
  )
  (princ)
)

 

  

0 Likes
Message 11 of 21

komondormrex
Mentor
Mentor
Accepted solution

hatch origin should be 2 coordinates point, thus line 43 has to go as

(vlax-put hatch_object 'origin (list (car center) (cadr center)))
0 Likes
Message 12 of 21

Hannan1
Advocate
Advocate

Cheers..... Thanks Everyone.

0 Likes
Message 13 of 21

Hannan1
Advocate
Advocate

Hello, 

I was tested on Hatch that have background color properties, it gives me anerror: Automation Error. Invalid input

How can we fix those issues.

0 Likes
Message 14 of 21

komondormrex
Mentor
Mentor

hey,

maybe the problem is with your using vlax in every occasion, while it surely is needed in your case when you are getting/putting points, cause 

(vla-get-origin...) gets an array

and (vlax-get ... 'origin) gets a list

in case with colors both return vla-object, no difference which one to use. vla is shorter.

check the following. works fine for hatches with background colors.

komondormrex_0-1738753495260.png

 

 

(defun c:RectHatch (/ len wid center pv pt1 pt2 source_hatch pattern hatch_object outer_loop rectangle)
  (prompt "\nRectangle with Hatch and Associated Boundary\n")
  (initget 7)
  (setq len (getreal "\nEnter the length of the rectangle: "))
  (initget 7)
  (setq wid (getreal "\nEnter the width of the rectangle: "))
  (setq center (getpoint "\nSpecify the center point of the rectangle: "))

  (setq source_hatch (car (entsel "\nSelect an existing hatch to match properties: ")))

  (if (and source_hatch (eq (cdr (assoc 0 (entget source_hatch))) "HATCH"))
    (progn
      (setq vla-source-hatch (vlax-ename->vla-object source_hatch))
      (setq pattern (vla-get-patternname vla-source-hatch))

      (setq pv  (list (* len 0.5) (* wid 0.5))
            pt2 (mapcar '(lambda (u v) (+ u v)) center pv)
            pt1 (mapcar '(lambda (u v) (- u v)) center pv))

      (command "_rectangle" "_non" pt1 "_non" pt2)
      (setq rectangle (vlax-ename->vla-object (entlast)))

      (setq hatch_object (vla-addhatch
                           (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
                           achatchpatterntypepredefined
                           pattern
                           :vlax-true
                           achatchobject))

      (setq outer_loop (vlax-make-safearray vlax-vbobject '(0 . 0)))
      (vlax-safearray-put-element outer_loop 0 rectangle)
      (vla-appendouterloop hatch_object outer_loop)
      
      (vla-put-patternscale hatch_object (vla-get-patternscale vla-source-hatch))
      (vla-put-patternangle hatch_object (vla-get-patternangle vla-source-hatch))
      (vla-put-patterndouble hatch_object (vla-get-patterndouble vla-source-hatch)) 
      (vla-put-layer hatch_object (vla-get-layer vla-source-hatch))
      (vla-put-backgroundcolor hatch_object (vla-get-backgroundcolor vla-source-hatch))
      (vlax-put hatch_object 'origin (list (car center) (cadr center)))

      (vla-update hatch_object)

      (princ (strcat "\nRectangle with Hatch created successfully on layer: " (vla-get-layer hatch_object)))
    )
    (princ "\nError: Please select a valid hatch to match properties.")
  )
  (princ)
)

 

 

and finally

"If the PatternType property is set to acHatchPatternTypePreDefined or acHatchPatternTypeCustomDefined, then the PatternDouble property is not used."

so there is no use for PatternDouble

 

0 Likes
Message 15 of 21

Hannan1
Advocate
Advocate

Have you tested already? 

For me still same error.

0 Likes
Message 16 of 21

komondormrex
Mentor
Mentor

yep i tested it lightly, but you'd better post an example with source hatch that gets the error. 

0 Likes
Message 17 of 21

Hannan1
Advocate
Advocate

Find the attached Sample hatches you can test on those,

Hatch pattern GRAVL1 & CONCRE gets; error: Automation Error. Invalid input

0 Likes
Message 18 of 21

komondormrex
Mentor
Mentor

well, i may suggest that these hatches are custom made and you do not have their definitions on your computer.

0 Likes
Message 19 of 21

Hannan1
Advocate
Advocate

Ohh, That's why it's not able to create,

Thanks @komondormrex 

0 Likes
Message 20 of 21

komondormrex
Mentor
Mentor

check this mod thou, which catches this error

(defun c:RectHatch (/ len wid center pv pt1 pt2 source_hatch pattern hatch_object outer_loop rectangle)
  (prompt "\nRectangle with Hatch and Associated Boundary\n")
  (initget 7)
  (setq len (getreal "\nEnter the length of the rectangle: "))
  (initget 7)
  (setq wid (getreal "\nEnter the width of the rectangle: "))
  (setq center (getpoint "\nSpecify the center point of the rectangle: "))

  (setq source_hatch (car (entsel "\nSelect an existing hatch to match properties: ")))

  (if (and source_hatch (eq (cdr (assoc 0 (entget source_hatch))) "HATCH"))
    (progn
      (setq vla-source-hatch (vlax-ename->vla-object source_hatch))
      (setq pattern (vla-get-patternname vla-source-hatch))

      (setq pv  (list (* len 0.5) (* wid 0.5))
            pt2 (mapcar '(lambda (u v) (+ u v)) center pv)
            pt1 (mapcar '(lambda (u v) (- u v)) center pv))


      (if (vl-catch-all-error-p (setq hatch_object (vl-catch-all-apply 'vla-addhatch
	                           (list (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
		                           achatchpatterntypepredefined
		                           pattern
		                           :vlax-true
		                           achatchobject
				  )
				)
			      )
	  )
		(alert (strcat "Cannot find definition for \"" pattern "\" hatch"))
		(progn
		        (command "_rectangle" "_non" pt1 "_non" pt2)
      			(setq rectangle (vlax-ename->vla-object (entlast)))

		      (setq outer_loop (vlax-make-safearray vlax-vbobject '(0 . 0)))
		      (vlax-safearray-put-element outer_loop 0 rectangle)
		      (vla-appendouterloop hatch_object outer_loop)
		      
		      (vla-put-patternscale hatch_object (vla-get-patternscale vla-source-hatch))
		      (vla-put-patternangle hatch_object (vla-get-patternangle vla-source-hatch))
		      (vla-put-patterndouble hatch_object (vla-get-patterndouble vla-source-hatch)) 
		      (vla-put-layer hatch_object (vla-get-layer vla-source-hatch))
		      (vla-put-backgroundcolor hatch_object (vla-get-backgroundcolor vla-source-hatch))
		      (vla-put-truecolor hatch_object (vla-get-truecolor vla-source-hatch))
		      (vlax-put hatch_object 'origin (list (car center) (cadr center)))

		      (vla-update hatch_object)

		      (princ (strcat "\nRectangle with Hatch created successfully on layer: " (vla-get-layer hatch_object)))
		)
	)
    )
    (princ "\nError: Please select a valid hatch to match properties.")
  )
  (princ)
)

 

0 Likes