Jump to content

Creating attribute fields


Recommended Posts

Posted

Been blowin y'all up the last couple days. Just want to say thanks for everything, and ask yet another question. What's the best way to go about generating an attribute field that references other blocks to perform a calculation? From what I've found, vla seems to be the answer. Can someone help me get started? I want an attribute field to reference pairs of points to calculate a difference in elevation between two points as shown below. 

 

image.thumb.png.eeabc34235fee4830c771b7e2e31e444.png

I have been able to do this manually, but I need to write a routine that will build my block automatically and set all attribute fields. From what I have found it can be impossible to entmake the attribute field. If I can't use entmake, then will i need to use vla functions? If I use vla functions, then I assume I will need to convert back to entity's once done with creating. Or do I need to keep everything as vla?

 

The formula would be (z2-z1)/(x2-x1)*100 to yield a slope percentage. I'd do this for every pair of points. 

 

Any help would be appreciated. 

Posted (edited)

Here's what I have so far... it doesn't currently work, any ideas why?

(setq NW_SW (entmakex (list '(0 . "ATTDEF")				  
				  '(8 . "TS_SLOPES")
				  (cons 10 (list (/ h 3) (* w 0.05) 0.0))
				  '(40 . 50)
				  (cons 1 (strcat "%<\AcExpr ((%<\%<\AcObjProp Object(%<\_ObjId "
						  (LM:objectID (vlax-ename->vla-object (cdr (assoc -1 (nth 1 GSlist)))))
						  ">%).InsertionPoint \f \"%lu2%pt4\">%>% -%<"
						  (LM:objectID (vlax-ename->vla-object (cdr (assoc -1 (nth 0 GSlist)))))
						  ">% )/(%<\AcObjProp Object(%<\_ObjId "
						  (LM:objectID (vlax-ename->vla-object (cdr (assoc -1 (nth 1 GSlist)))))
						  ">%).InsertionPoint \f \"%lu2%pt4\">% -%<\%<\AcObjProp Object(%<\_ObjId "
						  (LM:objectID (vlax-ename->vla-object (cdr (assoc -1 (nth 0 GSlist)))))
						  ">%).InsertionPoint \f \"%lu2%pt2\">%>% )*100)>%"))			
				  (cons 50  (* 90 (/ pi 180)))
				  '(41 . 1.0)
				  '(51 . 0.0)
				  '(7 . "Standard")
				  '(71 . 0)
				  '(72 . 0)
				  '(11 0.0 0.0 0.0)
				  '(210 0.0 0.0 1.0)
				  '(100 . "AcDbAttributeDefinition")				  
				  '(280 . 0)
				  '(3 . "")
				  '(2 . "NWSW_SLOPE")
				  '(70 . 0)
				  '(73 . 0)
				  '(74 . 0)
				  '(280 . 1)
				  )))

GSlist is a list that I append the initially mentioned points to so that I can reference them specifically. I'm sing Lee Macs object ID function to retrieve object ids. 

Edited by brandalf_the_semiGray
Clarification on what GSlist is
Posted (edited)

I just removed my comments need real samples to look at post a dwg. Understand the slope bit but not what the actual output would be, Using 2 Autocad POINTS may be easier.

Edited by BIGAL
Posted (edited)

I will post one when i get to work tomorrow. Basically this is part of a block I'm making. Its an attribute definition I'm trying to use entmakex to generate. The attribute needs to reference the two blocks which are basically points. I need them to be blocks for when i call civil 3d's moveblockstosurface command. I suppose i could try to see if there's a way to move points to a surface, but I'd still need to reference the points in my attribute definition. The issue I'm currently having is that I'm not sure which dxf codes are necessary for attdef in order to do what I'm trying to do. I did use a routine I found that prints all the dxf codes for a selected object to the command line, and so I made one of these attributes with references to use as a template. When i did that there was a dxf code of the following form:

 (120 . "{ACAD_XDICTIONARY")

(330 . <entity name> some unknown entity)

(120 . "}")

 

Any ideas what entity it could be referencing? Is it possible the field itself is made into an entity? Currently I'm putting the field description in the dxf slot for (1 . " ") which is the default slot. The default slot is the one where I created the fields in the block I made on my own. 

Edited by brandalf_the_semiGray
Posted (edited)

Ok there is a CIV3D label 2 points slope its built in. Its a leader style. In saying that I know I did an auto points to surface lisp its here at Cadtutor, same as blocks to surface, so could do a auto label possibly. If you edit the Z label it should update as its cogo points now. Is this more what you want ? Where are the 2 points coming from. is it 2 from a rectang etc ? Could add a description to point like P11 P12 ie point 1 going to point2 then P21 P22, P31 P32 and so on as matched pairs. Can just use point numbers 1001,1002 - 1003,1004

Edited by BIGAL
Posted

Do you know whether that 2 points slope multileader updates without a regen? Would the points I use then be COGO points?

 

Im not sure what you mean about where are the points coming from?

Posted (edited)

@BIGAL I've attached a drawing that has an attribute set up the way I want it to be. I've also attached my current lisp routine. 

 

Here's a routine I found that prints the DXF info (routine attached as well):

(defun C:PRINTDXF2 ( )                     ; Define function

  (if (setq pick (entsel))
    (setq ent (car pick))
    (exit)
  )

; (setq ent (entlast))                    ; Set ent to last entity.
  (setq entl (entget ent))                ; Set entl to association list of last entity

  (setq ct 0)                             ; Set ct (a counter) to 0.
  (textpage)                              ; Switch to the text screen.
  (princ "\nentget of last entity:")      ; Print dxf data of last entity to screen

  (repeat (length entl)                   ; Repeat for number of members in list:
    (print (nth ct entl))                 ; Print a newline, then each list member
    (setq ct (1+ ct))                     ; Increments the counter by one.
  )                                       ; End of repeat
  (princ)                                 ; Exit quietly.
)    

 

 

And here's the output when I click on my attribute.

Command: PRINTDXF2
Select object:
entget of last entity:
(-1 . <Entity name: 1d092c4d1b0>)
(0 . "ATTDEF")
(5 . "878B")
(102 . "{ACAD_XDICTIONARY")					;PARTICULAR PIECE THAT I DON'T KNOW HOW TO HANDLE
(360 . <Entity name: 1d092c4d1c0>)
(102 . "}")
(330 . <Entity name: 1d092c4e1f0>)
(100 . "AcDbEntity")
(67 . 0)
(410 . "Model")
(8 . "0")
(100 . "AcDbText")
(10 2062.46 7309.72 0.0)
(40 . 50.0)
(1 . "0.000000")
(50 . 0.0)
(41 . 1.0)
(51 . 0.0)
(7 . "Standard")
(71 . 0)
(72 . 0)
(11 0.0 0.0 0.0)
(210 0.0 0.0 1.0)
(100 . "AcDbAttributeDefinition")
(280 . 0)
(3 . "")
(2 . "SLOPE")
(70 . 0)
(73 . 0)
(74 . 0)
(280 . 1)

 

Here's my current dxf designations:

      (setq NW_SW (entmakex (list '(0 . "ATTDEF")
				  '(8 . "TS_SLOPES")
				  (cons 10 (list (/ h 3) (* w 0.05) 0.0))
				  '(40 . 50)
				  (cons 1 (strcat "%<\AcExpr ((%<\%<\AcObjProp Object(%<\_ObjId "
						  (LM:objectID (vlax-ename->vla-object (cdr (assoc -1 (nth 1 GSlist)))))
						  ">%).InsertionPoint \f \"%lu2%pt4\">%>% -%<"
						  (LM:objectID (vlax-ename->vla-object (cdr (assoc -1 (nth 0 GSlist)))))
						  ">% )/(%<\AcObjProp Object(%<\_ObjId "
						  (LM:objectID (vlax-ename->vla-object (cdr (assoc -1 (nth 1 GSlist)))))
						  ">%).InsertionPoint \f \"%lu2%pt4\">% -%<\%<\AcObjProp Object(%<\_ObjId "
						  (LM:objectID (vlax-ename->vla-object (cdr (assoc -1 (nth 0 GSlist)))))
						  ">%).InsertionPoint \f \"%lu2%pt2\">%>% )*100)>%"))			
				  (cons 50  (* 90 (/ pi 180)))
				  '(41 . 1.0)
				  '(51 . 0.0)
				  '(7 . "Standard")
				  '(71 . 0)
				  '(72 . 0)
				  '(11 0.0 0.0 0.0)
				  '(210 0.0 0.0 1.0)
				  '(100 . "AcDbAttributeDefinition")				  
				  '(280 . 0)
				  '(3 . "")
				  '(2 . "NWSW_SLOPE")
				  '(70 . 0)
				  '(73 . 0)
				  '(74 . 0)
				  '(280 . 1)
				  )))

 

 

EDIT:

Could the ACAD_XDICTIONARY being referenced be some sort of MTEXT that holds all the field data?

TEST.dwg

PRINTDXF2.LSP genBlocks.lsp

Edited by brandalf_the_semiGray
just had a thought...
Posted

I would strongly advise against creating Fields using entmake/entmakex: whilst it is theoretically possible to create a Field using only Vanilla AutoLISP methods (as this old thread demonstrates), you would need to create the definition of the Extension Dictionary attached to the attribute definition, the ACAD_FIELD dictionary contained within the Extension Dictionary, the TEXT dictionary contained within the ACAD_FIELD dictionary, the FIELD entity container, and finally, the FIELD entity which contains the actual field expression.

 

Compare the above with the ActiveX method of simply populating the object content with the field expression which is automatically recognised as such and creates the above automatically.

  • Like 1
Posted (edited)
43 minutes ago, Lee Mac said:

I would strongly advise against creating Fields using entmake/entmakex: whilst it is theoretically possible to create a Field using only Vanilla AutoLISP methods (as this old thread demonstrates), you would need to create the definition of the Extension Dictionary attached to the attribute definition, the ACAD_FIELD dictionary contained within the Extension Dictionary, the TEXT dictionary contained within the ACAD_FIELD dictionary, the FIELD entity container, and finally, the FIELD entity which contains the actual field expression.

 

Compare the above with the ActiveX method of simply populating the object content with the field expression which is automatically recognised as such and creates the above automatically.

Can you point me in the direction of materials that would instruct in the activex method? in creating this via activex method, will I then need to convert the attribute to an entity object type for compatibility with the rest of my routine.

 

 

EDIT: @Lee Mac I found your copy field function. I am thinking I could use the pieces of that that actually put the field into an object. The one question I still really have is related to compatibility with vanilla entities. In the event that I add the field through activex, will i render the attribute unusable to vanilla lisp, or when the activex method runs, does it just create everything necessary for the field and compatibility remains? Any help is appreciated. I'm doing my best to grasp all of this stuff. It's a bit like trying to drink from a firehose haha. 

Edited by brandalf_the_semiGray
Posted (edited)

Isn't this what you want, you can customise the style. No code produced image. It could possibly be automated, but manually only takes seconds. Just convert points to a cogo point on a surface so Z is auto worked out.

 

image.thumb.png.3f280217e2e0d3e37ab76b534d25c92f.png

 

 

 

 

 

 

screenshot154.png

Edited by BIGAL
Posted
2 hours ago, BIGAL said:

Isn't this what you want, you can customise the style. No code produced image. It could possibly be automated, but manually only takes seconds. Just convert points to a cogo point on a surface so Z is auto worked out.

 

image.thumb.png.3f280217e2e0d3e37ab76b534d25c92f.png

 

 

 

 

 

 

screenshot154.png

It's close, but based on the slopes i need to be able to change the color of a block for quick visual inspection.

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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.

×
×
  • Create New...