ObjectDBX - draw lines in a virtual "acdbObj" and copy them back to "acadObj"

ObjectDBX - draw lines in a virtual "acdbObj" and copy them back to "acadObj"

surfer96
Advocate Advocate
1,233 Views
7 Replies
Message 1 of 8

ObjectDBX - draw lines in a virtual "acdbObj" and copy them back to "acadObj"

surfer96
Advocate
Advocate

I would like to use ObjectDBX in order to generate multiple "virtual" lines in an "acdbobj" and finally copy them back to the current AutoCAD document.

 

Is it possible to generate a line in "acdbobj" simply using:

(setq lineObj (vlax-invoke (vla-get-ModelSpace (vla-get-Database doc)) 'addline pt1 pt2)

 

Is "acdbobj" what is usually called the database object?

The purpose of this test is to find out, wether using ObjectDBX will fasten looping.

 

 

(vl-load-com)
(defun c:addrdlines (/ bw nl r1 r2 pt1 pt2 lineObj dbp)

  (setq	acadObj	   (vlax-get-acad-object)
	c_doc	   (vla-get-Activedocument acadObj)
	modelSpace (vla-get-ModelSpace c_doc)
  )

  ;; Load the ObjectDBX library
  (if (= acLibImport nil)
    (progn
      (vlax-import-type-library
	:tlb-filename
	"C:\\Program Files\\Common Files\\Autodesk Shared\\axdb21enu.tlb"
	:methods-prefix
	"acdbm-"
	:properties-prefix
	"acdbp-"
	:constants-prefix
	"acdbc-"
       )
      (setq acLibImport T)
    )
  )

  ;; Create a reference to the ObjectDBX object
  (setq acdbObj (vlax-create-object "ObjectDBX.AxDbDocument.21"))

  (setq	bw 100.				;box width
	nl 10				;number of lines
  )

  ;; CREATE LINES IN MODELSPACE OF acdbObj
;; ??? (repeat nl (setq r1 (* (LM:rand) bw) r2 (* (LM:rand) bw) pt1 (list 0. r1 0.) pt2 (list bw r2 0.) ) (setq lineObj (vlax-invoke modelSpace 'addline pt1 pt2)) ;random line / distance between points ) ;end repeat ;; COPY ALL LINES FROM MODELSPACE "acdbObj" to MODELSPACE "acadObj"
;; ???
;; Close the in memory drawing
(vlax-release-object acdbObj) ) ;end defun ;;;LM:rand (defun LM:rand (/ a c m) (setq m 4294967296.0 a 1664525.0 c 1013904223.0 $xn (rem (+ c (* a (cond ($xn) ((getvar 'date)) ) ) ) m ) ) (/ $xn m) )

 

 

0 Likes
Accepted solutions (1)
1,234 Views
7 Replies
Replies (7)
Message 2 of 8

surfer96
Advocate
Advocate

The code below shows what I got so far, but unfortunately it returns:

error: bad argument type: VLA-OBJECT nil

 

(vl-load-com)
(defun c:addrdlines (/ bw nl r1 r2 pt1 pt2 lineObj)

  (setq	acadObj	   (vlax-get-acad-object)
	c_doc	   (vla-get-Activedocument acadObj)
	modelSpace (vla-get-ModelSpace c_doc)
  )

  ;; Load the ObjectDBX library
  (if (= acLibImport nil)
    (progn
      (vlax-import-type-library
	:tlb-filename
	"C:\\Program Files\\Common Files\\Autodesk Shared\\axdb21enu.tlb"
	:methods-prefix
	"acdbm-"
	:properties-prefix
	"acdbp-"
	:constants-prefix
	"acdbc-"
       )
      (setq acLibImport T)
    )
  )

  ;; Create a reference to the ObjectDBX object
  (setq acdbObj (vlax-create-object "ObjectDBX.AxDbDocument.21"))

  (setq	bw 100.				;box width
	nl 10				;number of lines
  )

  ;; CREATE LINES IN MODELSPACE OF acdbObj
  (repeat nl
    (setq
      r1  (* (LM:rand) bw)
      r2  (* (LM:rand) bw)
      pt1 (list 0. r1 0.)
      pt2 (list bw r2 0.)
    )
    (setq lineObj (vlax-invoke
		    (vla-get-ModelSpace acdbObj)
		    'addline
		    pt1
		    pt2
		  )
    )					;random lines
  )					;end repeat

  ;; Copy objects
  (vlax-for eachObj (vla-get-ModelSpace acdbObj)
    (vlax-safearray-put-element objCollection count eachObj)
    (setq count (1+ count))
  )

  ;; Copy object and get back a collection of the new objects (copies)
  (setq	retObjects
	 (vla-CopyObjects
	   acdbObj
	   objCollection
	   (vla-get-ModelSpace (vla-get-Database c_doc))
	 )
  )

  (vla-ZoomExtents acadObj)
  (alert "Model space objects copied.")

  ;; Close the in memory drawing
  (vlax-release-object acdbObj)

)					;end defun

;;;LM:rand
(defun LM:rand (/ a c m)
  (setq	m   4294967296.0
	a   1664525.0
	c   1013904223.0
	$xn (rem (+ c
		    (* a
		       (cond ($xn)
			     ((getvar 'date))
		       )
		    )
		 )
		 m
	    )
  )
  (/ $xn m)
)

 

 

0 Likes
Message 3 of 8

CodeDing
Advisor
Advisor

@surfer96 ,

 

While I may not answer your question directly, to my knowledge ENTMAKE/ENTMAKEX are the fastest ways to create lines in AutoCAD. Faster than VL/VLA/VLAX.

(setq lineObj (entmakex (list (cons 0 "LINE") (cons 10 pt1) (cons 11 pt2))))

User tests

User Tests

Best,

~DD

 

0 Likes
Message 4 of 8

surfer96
Advocate
Advocate

@CodeDing 

I think velocity depends on what you want to do with the geometry created later on.

By accident I tried the following alternatives today:

 

(setq lineObj (vlax-invoke modelSpace 'addline pt1 pt2))
(entmakex (list '(0 . "line") (cons 10 pt1) (cons 11 pt2))

(setq lineObj (vla-AddLine modelSpace pt1 pt2))

 

Multiple random lines were created and the distance between their endpoints and startpoints evaluated.

'addline and entmake had the same speed, whereas vla-AddLine was very much slower due to the complex distance calculation for vlax-3d-points.

 

I therefore chose the vla-AddLine method to find out if it can be further accelerated by using ObjectDBX...

0 Likes
Message 5 of 8

CodeDing
Advisor
Advisor

@surfer96 ,

 

For what it's worth, it appears "vlax-invoke" is possibly obsolete, and "vlax-invoke-method" is the updated version. Try this?

0 Likes
Message 6 of 8

surfer96
Advocate
Advocate

The new "vlax-invoke-method" does not seem to make a difference.

 

Moreover the object collection variable (to collect all lines to be copied) had not been defined but there still must be errors in the code. I wonder if the lines are properly generated in acdbObj at all.

 

  ;; define safearray for objects
  (setq	objCollection
	 (vlax-make-safearray
	   vlax-vbObject
	   (cons
	     0
	     (- (vla-get-Count (vla-get-ModelSpace acdbObj)) 1)
	   )
	 )
	count 0
  )

  ;; put elements to selfarray 
  (vlax-for eachObj (vla-get-ModelSpace acdbObj)
    (vlax-safearray-put-element objCollection count eachObj)
    (setq count (1+ count))
  )
0 Likes
Message 7 of 8

surfer96
Advocate
Advocate
Accepted solution

I found a solution using "vla-addline" instead of "vlax-invoke-method 'addline".

Creating 1000 lines was not faster, but even slower with ODBX:

 

With ODBX
Command: REPEAT_RDLINES_ODBX
Number of Lines:1000
Time Elapsed in Millisecs: 250
Millisecs per Loop:4

 

Without ODBX
Command: REPEAT_RDLINES
Number of Lines:1000
Time Elapsed in Millisecs: 187
Millisecs per Loop:5

Message 8 of 8

CodeDing
Advisor
Advisor

@surfer96 ,

 

Glad you got your solution! Also, this may seem tedious but based on your equation in your lisp, this:

"Millisecs per Loop:"

Should actually say this:

"Loops per Millisecond:"
0 Likes