Author Topic: odbx : workaround to get active layer  (Read 3500 times)

0 Members and 1 Guest are viewing this topic.

BrunoToniutti

  • Guest
odbx : workaround to get active layer
« on: March 20, 2007, 12:45:30 PM »
hi,
I don't know if a solution have been posted before, if yes sorry, but I read so many times that there is no solution. It's very usefull for me.
May be by the same way it'll possible to create an odbx_SetActiveLayer

Code: [Select]
;function : identify the active layer via odbx
;use : (odbx_activeLayerName odbx)
;version : 1.070320 beta
;notes : 1.070320 few tested with MAP 3D 2007 and Win XP sp2
;realization : Bruno Toniutti
;special thanks to : Tony Tanzillo, James Buzbee, Tim Willey

(defun odbx_activeLayerName (odbx / lsman layerStateName layerStateObj arrayXdataCode arrayXdataValue)
  (setq lsman (vla-GetInterfaceObject (vlax-get-acad-object) "AutoCAD.AcadLayerStateManager.17"))
  (vla-SetDatabase lsman (vla-get-database odbx))
  (setq layerStateName (rtos (getvar "cdate") 2))
  (vla-Save lsman layerStateName 1023)
  ; for test purpose => export layer state saved
  (vla-export lsman layerStateName (strcat (vl-filename-directory (setq tmp (vla-get-name odbx))) "\\" (vl-filename-base tmp) ".las"))
  ;
  (vlax-release-object lsman)
  (setq layerStateObj
         (vla-item
           (vla-item
             (vla-GetExtensionDictionary (vla-get-Layers odbx))
             "ACAD_LAYERSTATES"
           )
           layerStateName
         )
  )
  (vla-GetXRecordData layerStateObj 'arrayXdataCode 'arrayXdataValue)
  (vlax-release-object layerStateObj)
  (vlax-variant-value (nth 3 (vlax-safearray->list arrayXdataValue)))
)

; test
(setq file (getfiled "Select a file" "" "dwg" 0))
(setq odbx (vla-getinterfaceobject (vlax-get-acad-object) "ObjectDBX.AxDbDocument.17"))
(vla-open odbx file)
(odbx_ActiveLayerName odbx)
(vlax-release-object odbx)
(setq odbx nil file nil)

Bruno Toniutti
« Last Edit: March 21, 2007, 11:19:50 AM by BrunoToniutti »

T.Willey

  • Needs a day job
  • Posts: 5237
Re: odbx : workaround to get active layer
« Reply #1 on: March 20, 2007, 01:04:24 PM »
Welcome to theswamp Bruno, but I still don't see a way to get the active layer in a drawing opened with objectDBX.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Jeff_M

  • King Gator
  • Posts: 3975
  • C3D user & customizer
Re: odbx : workaround to get active layer
« Reply #2 on: March 20, 2007, 01:57:48 PM »
Actually, I just discovered you CAN get the "current" layer in an ObjectDBX document. Just draw a temporary object in the ODBX doc. and query it's layer. It will be the layer last set to current in that drawing. Delete the temp. object.

To test this, I created a new drawing "c:\test" and added 2 new layers to it. I then set the "Layer2" current, saved and closed. Then I opened the test.dwg with ODBX, drew a line, queried the layer, deleted the line.

Code: [Select]
(defun oDBX_activelayer (odbx / lin lay)
  (setq lin (vlax-invoke (vla-get-modelspace odbx) 'addline '(0.0 0.0 0.0) '(1.0 1.0 0.0)))
  (setq lay (vla-get-layer lin))
  (vla-delete lin)
  lay
  )

BrunoToniutti

  • Guest
Re: odbx : workaround to get active layer
« Reply #3 on: March 20, 2007, 02:13:28 PM »
Welcome to theswamp Bruno, but I still don't see a way to get the active layer in a drawing opened with objectDBX.

thx,
Tim,
this function open a file via odbx and returns his active layer's name, simply because LayerStateManager save it. So I don't really understand your reply, what do you get ?

too, I think it's possible to set the active layer via odbx.
- create a layers state
- modify the active layer saved in this layers state
- restore this layer state

Jeff, I'll try this at work, but seems to be a nice workaround

Bruno Toniutti
« Last Edit: March 20, 2007, 02:29:34 PM by BrunoToniutti »

T.Willey

  • Needs a day job
  • Posts: 5237
Re: odbx : workaround to get active layer
« Reply #4 on: March 20, 2007, 02:44:05 PM »
Bruno,

  I misinterpreted what you were posting about.  I though you had a question, but you were posting something that works.  Sorry I didn't try the code.

Jeff,

  Good idea!  That never came to mind.


Thanks both!!  :-)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Jeff_M

  • King Gator
  • Posts: 3975
  • C3D user & customizer
Re: odbx : workaround to get active layer
« Reply #5 on: March 20, 2007, 02:47:30 PM »
Bruno, I'm not sure your code does what you think. In my test, it only returned the color of the last layer in the layers collection......
« Last Edit: March 20, 2007, 03:11:04 PM by Jeff_M »

BrunoToniutti

  • Guest
Re: odbx : workaround to get active layer
« Reply #6 on: March 21, 2007, 07:11:40 AM »
yes I hope that works or ...will work perfectly  :roll:

Jeff
I tested your solution, it works and thx :)
but its necessary to manage case when the active layer is locked.
- save layers state
- unlock all layers
- drawn something to get his layer
- restore layers state

as I explained before, I want to create too an odbx_setActiveLayer  so I need to be sure that mine odbx_activeLayerName works too.

I have just modified it to get a .las file, i added :
(vla-export lsman layerStateName (strcat (vl-filename-directory (setq tmp (vla-get-name odbx))) "\\" (vl-filename-base tmp) ".las"))
in my dwg file, "Calque1" is the active layer, las file exported :
Code: [Select]
0
LAYERSTATEDICTIONARY
  0
LAYERSTATE
  1
20070321.11294341
 91
1023
301

290
0
302
Calque1
  8
Calque2
 90
8
 62
6
370
-3
  6
Continuous
  2
Color_6
  8
Calque1
 90
13
 62
50
370
-3
  6
Continuous
  2
Color_50
  8
0
 90
8
 62
7
370
-3
  6
Continuous
  2
Color_7
code 302 gives the active layer, to extract it I use :
(vlax-variant-value (nth 3 (vlax-safearray->list arrayXdataValue)))
but may be this code 302 is not always in fourth position, so could you post a las file to see differences?
TIA

(note : now, odbx is an argument of odbx_activeLayerName)

Bruno

Jeff_M

  • King Gator
  • Posts: 3975
  • C3D user & customizer
Re: odbx : workaround to get active layer
« Reply #7 on: March 21, 2007, 11:10:51 AM »
Hi Bruno,
I see a couple things.

First, I was testing this originally in R2002. The LSM in 2002 does not output a 302 code, so I'm not sure what version started using it for the current layer. If you won't be using this in earlier versions then I guess it doesn't matter.

Second, the 4th item in the LAS you posted is not the 302 code.......scratch that, I see by testing in R2007 the XRecord data does appear to consistently be the 4th item.....but I think I'd still use the following.

Third, to insure you use the correct (nth), find the position of the 302 in the arrayXdataCode. This will be the position of the value in the arrayXdataValue.

Here's a snip from the beginning of a LAS I did in R2007:
Quote from: LAS file
  0
LAYERSTATEDICTIONARY
  0
LAYERSTATE
  1
current
 91
1023
301

290
0
302
pt-points
  8
C-ROAD-SCTN-LABL
 90
8
While composing this reply, I wondered why you still need to use the LSM. Just check if the current layer is locked before attempting to delete the temp. object and unlock it.

Jeff_M

  • King Gator
  • Posts: 3975
  • C3D user & customizer
Re: odbx : workaround to get active layer
« Reply #8 on: March 21, 2007, 11:13:25 AM »
Oh, and may I ask why you want/need to set a layer current in a remote dwg? I can't think of any reason I would need to do so, so I'm just curious.

BrunoToniutti

  • Guest
Re: odbx : workaround to get active layer
« Reply #9 on: March 21, 2007, 11:54:09 AM »
Jeff, thx for your notes, that help me to remove some potential problems.

after having read your reply of yesterday, it's exactly what i'm working on today : evaluate position of code 302 and return nil if code 302 doesn't exist

Code: [Select]
;function : identify the active layer via odbx
;use : (odbx_activeLayerName odbx)
;return : the active layer or nil
;version : 1.070320 beta
;          1.070321 evaluation of position of code 302 in a layers state
;notes : 1.070321 tested only with MAP 3D 2007 and Win XP sp2
;realization : Bruno Toniutti
;special thanks to : Tony Tanzillo, James Buzbee, Tim Willey, Jeff Mishler

(defun odbx_activeLayerName (odbx / lsman layerStateName layerStateObj arrayXdataCode arrayXdataValue tmp)
  (setq lsman (vla-GetInterfaceObject (vlax-get-acad-object) "AutoCAD.AcadLayerStateManager.17"))
  (vla-SetDatabase lsman (vla-get-database odbx))
  (setq layerStateName (rtos (getvar "cdate") 2))
  (vla-Save lsman layerStateName 1023)
  ; for debug purpose => export layer state saved
  ;(vla-export lsman layerStateName (strcat (vl-filename-directory (setq tmp (vla-get-name odbx))) "\\" (vl-filename-base tmp) ".las"))
  ;
  (vlax-release-object lsman)
  (setq layerStateObj
         (vla-item
           (vla-item
             (vla-GetExtensionDictionary (vla-get-Layers odbx))
             "ACAD_LAYERSTATES"
           )
           layerStateName
         )
  )
  (vla-GetXRecordData layerStateObj 'arrayXdataCode 'arrayXdataValue)
  (vlax-release-object layerStateObj)
  ; code 302 give the active layer saved in a layer state
  (if (setq tmp (vl-position 302 (vlax-safearray->list arrayXdataCode)))
    (vlax-variant-value (nth tmp (vlax-safearray->list arrayXdataValue)))
    nil
  )
)

; test
(setq file (getfiled "Select a file" "" "dwg" 0))
(setq odbx (vla-getinterfaceobject (vlax-get-acad-object) "ObjectDBX.AxDbDocument.17"))
(vla-open odbx file)
(odbx_ActiveLayerName odbx)
(vlax-release-object odbx)
(setq odbx nil file nil

why...
first, I analyse and correct problems on tens of thousands of files per year, main of corrections are made via batch process, so I always search new methodes to increase speed : odbx is very important for me.

second, the challenge  :-) I always read that it's not possible...

ok now I'm working on odbx_setActiveLayer

Bruno Toniutti

Jeff_M

  • King Gator
  • Posts: 3975
  • C3D user & customizer
Re: odbx : workaround to get active layer
« Reply #10 on: March 21, 2007, 03:42:24 PM »

second, the challenge  :-) I always read that it's not possible...

OK, that's good enough for me :-) that's why I start 80% of my coding.