Author Topic: Xref Attached or overlay  (Read 3373 times)

0 Members and 1 Guest are viewing this topic.

Bryco

  • Water Moccasin
  • Posts: 1849
Xref Attached or overlay
« on: March 16, 2006, 01:51:55 AM »
I use  SomeCallMeDave's vbassoc function and I have Frank's Vlax class. Since I don't know lisp the latter is a bit hard to use. I'm messing with an xref class or functions right now and would like to know if an xref is attached or overlayed. So far it dxf code 70 seems to be what I need for the block but I am not sure how to go about it. Using SCMD's function I get a nil. I presume the answer is a list and and just needs processing correctly. Any ideas?
 Here is the vbassoc
Code: [Select]
'SomeCallMeDave
'http://www.vbdesign.net/expresso/showthread.php?postid=83887#post83887
'Changed pAcadObj As AcadObject to pAcadObj As Object to access imagedef as well
Public Function vbAssoc(pAcadObj, pDXFCode As Integer) As Variant

Dim VLisp As Object
Dim VLispFunc As Object
Dim varRetVal As Variant

Dim obj1 As Object
Dim obj2 As Object

Dim strHnd As String
Dim strVer As String

Dim lngCount As Long
Dim i As Long
Dim j As Long

On Error GoTo vbAssocError

strHnd = pAcadObj.handle
If Left(ThisDrawing.Application.Version, 2) = "16" Then
  Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.16")
Else
  Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.1")
End If

Set VLispFunc = VLisp.ActiveDocument.Functions

Set obj1 = VLispFunc.item("read").funcall("pDXF")
  varRetVal = VLispFunc.item("set").funcall(obj1, pDXFCode)
Set obj1 = VLispFunc.item("read").funcall("pHandle")
  varRetVal = VLispFunc.item("set").funcall(obj1, strHnd)
Set obj1 = VLispFunc.item("read").funcall("(vl-princ-to-string (cdr (assoc pDXF (entget (handent pHandle)))))")
  varRetVal = VLispFunc.item("eval").funcall(obj1)
 
vbAssoc = varRetVal

'clean up the newly created LISP symbols
Set obj1 = VLispFunc.item("read").funcall("(setq pDXF nil)")
  varRetVal = VLispFunc.item("eval").funcall(obj1)
Set obj1 = VLispFunc.item("read").funcall("(setq pHandle nil)")
  varRetVal = VLispFunc.item("eval").funcall(obj1)
 
'release the objects or Autocad gets squirrely (no offense RR)
Set obj2 = Nothing
Set obj1 = Nothing
Set VLispFunc = Nothing
Set VLisp = Nothing

Exit Function

vbAssocError:
  Set obj2 = Nothing
  Set obj1 = Nothing
  Set VLispFunc = Nothing
  Set VLisp = Nothing
  MsgBox "Error occurred " & Err.Description

End Function

Debug.Print "lisp", vbAssoc(oBlock, 2), vbAssoc(oBlock, 70)


Jeff_M

  • King Gator
  • Posts: 3944
  • C3D user & customizer
Re: Xref Attached or overlay
« Reply #1 on: March 16, 2006, 02:10:09 PM »
Bryco,
The problem is in the fact that the handle returned for the Block in the BlocksCollection is different than the one returned from the Block table in lisp.

I think this is due to one references the Block Table and the other references the Block_Record table........ a Block_Record does not have a group 70 code, whereas the Block does.

I'm looking now to see if there is an easy way around this....

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Xref Attached or overlay
« Reply #2 on: March 16, 2006, 02:24:54 PM »
Ouch tricky ground.

Jeff_M

  • King Gator
  • Posts: 3944
  • C3D user & customizer
Re: Xref Attached or overlay
« Reply #3 on: March 16, 2006, 02:51:26 PM »
OK, this works for me:
Code: [Select]
'SomeCallMeDave
'http://www.vbdesign.net/expresso/showthread.php?postid=83887#post83887
'Changed pAcadObj As AcadObject to pAcadObj As Object to access imagedef as well
'Modified by Jeff Mishler, March 2006, to get the Block table object, not Block_Record table object
Public Function vbAssoc(pAcadObj, pDXFCode As Integer) As Variant

Dim VLisp As Object
Dim VLispFunc As Object
Dim varRetVal As Variant

Dim obj1 As Object
Dim obj2 As Object

Dim strHnd As String
Dim strVer As String

Dim lngCount As Long
Dim i As Long
Dim j As Long

On Error GoTo vbAssocError
   
If Left(ThisDrawing.Application.Version, 2) = "16" Then
  Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.16")
Else
  Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.1")
End If

Set VLispFunc = VLisp.ActiveDocument.Functions

If Not TypeOf pAcadObj Is AcadBlock Then
    strHnd = pAcadObj.Handle
Else
    Dim lispStr As String
    lispStr = "(cdr (assoc 5 (entget (tblobjname " & Chr(34) & "Block" & Chr(34) & Chr(34) & pAcadObj.Name & Chr(34) & "))))"
    Set obj1 = VLispFunc.Item("read").funcall(lispStr)
    strHnd = VLispFunc.Item("eval").funcall(obj1)
End If
Set obj1 = VLispFunc.Item("read").funcall("pDXF")
  varRetVal = VLispFunc.Item("set").funcall(obj1, pDXFCode)
Set obj1 = VLispFunc.Item("read").funcall("pHandle")
  varRetVal = VLispFunc.Item("set").funcall(obj1, strHnd)
Set obj1 = VLispFunc.Item("read").funcall("(vl-princ-to-string (cdr (assoc pDXF (entget (handent pHandle)))))")
  varRetVal = VLispFunc.Item("eval").funcall(obj1)
 
vbAssoc = varRetVal

'clean up the newly created LISP symbols
Set obj1 = VLispFunc.Item("read").funcall("(setq pDXF nil)")
  varRetVal = VLispFunc.Item("eval").funcall(obj1)
Set obj1 = VLispFunc.Item("read").funcall("(setq pHandle nil)")
  varRetVal = VLispFunc.Item("eval").funcall(obj1)
 
'release the objects or Autocad gets squirrely (no offense RR)
Set obj2 = Nothing
Set obj1 = Nothing
Set VLispFunc = Nothing
Set VLisp = Nothing

Exit Function

vbAssocError:
  Set obj2 = Nothing
  Set obj1 = Nothing
  Set VLispFunc = Nothing
  Set VLisp = Nothing
  MsgBox "Error occurred " & Err.Description

End Function

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Xref Attached or overlay
« Reply #4 on: March 16, 2006, 04:21:02 PM »
Jeff you sure have a depth of knowledge. If you know the old joke about the bill for $100, here's 99 peanuts for knowing where to tap.
Hey what are swamp peanuts?
Thanks mate.

Jeff_M

  • King Gator
  • Posts: 3944
  • C3D user & customizer
Re: Xref Attached or overlay
« Reply #5 on: March 16, 2006, 04:39:15 PM »
Jeff you sure have a depth of knowledge. Thanks, but this is mainly due to encountering this same thing myself.
If you know the old joke about the bill for $100, here's 99 peanuts for knowing where to tap. I do, Thanks!
Hey what are swamp peanuts? The next line you posted does it for me :-D
Thanks mate.

My pleasure! And even though I had encountered this before, thereby allowing me to know WHAT the problem was, I hadn't sought a solution until now.....I was pleasantly surprised that it was a relatively simple fix.

Jeff_M

  • King Gator
  • Posts: 3944
  • C3D user & customizer
Re: Xref Attached or overlay
« Reply #6 on: March 16, 2006, 05:17:59 PM »
And based on MP's post over int the lisp forum, this will only work when checking the status of an Xref in the current drawing. If you want to use it on remote/ObjectDBX drawings it would need to be rewritten similar to what MP did.

Jeff_M

  • King Gator
  • Posts: 3944
  • C3D user & customizer
Re: Xref Attached or overlay
« Reply #7 on: March 16, 2006, 06:21:03 PM »
OK, replace this:
Code: [Select]
If Not TypeOf pAcadObj Is AcadBlock Then
    strHnd = pAcadObj.Handle
Else
    Dim lispStr As String
    lispStr = "(cdr (assoc 5 (entget (tblobjname " & Chr(34) & "Block" & Chr(34) & Chr(34) & pAcadObj.Name & Chr(34) & "))))"
    Set obj1 = VLispFunc.Item("read").funcall(lispStr)
    strHnd = VLispFunc.Item("eval").funcall(obj1)
End If
with this:
Code: [Select]
    strHnd = pAcadObj.Handle

If TypeOf pAcadObj Is AcadBlock Then
    strHnd = Hex(1 + Val("&H" & strHnd))
End If
which appears to work, but I seem to recall T.T. saying that this method cannot always be relied on.
* Jeff_M is off to research some more......

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Xref Attached or overlay
« Reply #8 on: March 19, 2006, 11:43:07 AM »
I've tried to find the block table in vba to no avail.
Using Hex(1 + Val("&H" & strHnd)) gave this message:
"Error occurred bad argument type:lentitype nil" and a crash.
This is a 137 file  (88 mb)dwg. that someone has given me to play with. No overlays, all attached and nested up the yingyang. For some reason they wont path even though they are all in the same folder so I'm also doing (if that's the word) a repathing sub. It seems the path can only be changed in the xref's immediate host, so now it gets time consuming. Getsubentity will give you the owner but that's not a good way to go. The owner of a block is always AcDbBlockTable so using the ownerid is a no go. That leaves cycling through each blocks ents to find if they are xrefs and putting everything in an ordered group of nesting depths.
Changing the paths on the parent dwg. then opening the child drawing and changing their paths etc etc. Slow and torturous.
(I'ld rather send a couple of hard  pipe hitting blokes with pliers and a blowtorch to work on the dwg the "Pulp Fiction" way.)
Wondering if I'm missing the easy way?

Glenn R

  • Water Moccasin
  • Posts: 1932
  • What idiot child of married cousins wrote this?!
Re: Xref Attached or overlay
« Reply #9 on: March 19, 2006, 10:05:49 PM »
Bryco,

Nope...you're not missing the easy way in VBA 'cause there aint none.
If you want to do what you describe, you will have to iterate the block table, check for xrefedness, then recursively loop that block table record's object to find any nested xrefs.

BTW, if all your xrefs are attached and they are nested, you actually can't change the path of a nested one. You correctly stated that you would have to open up the xref's host and modify it there.

Another reason why I don't use nested references - you lose control.

Cheers,
Glenn.
Me

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Xref Attached or overlay
« Reply #10 on: March 20, 2006, 10:28:34 PM »
Thanks Glenn. It's going to take me a while to get to the bot. of this. The block.counts of 0 and 1 (1 being the text -xref) should help a bit, perhaps.
I haven't found a reliable way to figure if an xref is loaded and kosher yet. I thought the block.path not having a / was enough but for some reason I have an xref without a fullpath and a count of larger than 1 that is happy as larry in the dwg.

Glenn R

  • Water Moccasin
  • Posts: 1932
  • What idiot child of married cousins wrote this?!
Re: Xref Attached or overlay
« Reply #11 on: March 20, 2006, 11:58:26 PM »
That's either:

A. The xref is found in the current drawing's folder, or
B. It's in the Acad search path, or,
C. It's in the application folder (location of acad.exe) or
D. A PROJECTNAME has been set for the current drawing and it's found the xref in one of those 'project paths'.

BTW, what version of AutoCAD are you using?

Cheers,
Glenn.
Me

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Xref Attached or overlay
« Reply #12 on: March 21, 2006, 01:29:39 AM »
2006 and liking it.

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Xref Attached or overlay
« Reply #13 on: March 28, 2006, 01:23:45 AM »
Oh didn't mention that there is about 500 files in the current drawings folder and only 1 decided to do the right thing.
There sure seems like a lot of variables associated with xrefs so after playing for a while I could only come up with I think such and such is happening.
 So far I've had no problem with Jeff's original upgrade.
I'm not sure how to know if an xref is resolved without using the dxf codes.
It's probably safe to say a block that is an xref with a count of 0 is an orphan.
I managed to get some code to work without finding the exact nesting status of each xref but it's a bit slow.
After making a collection of all the dwg files in a folder containing the xrefs, I would like to remove each file from the collection when a match is found with an xrefs name (faster) but since any xref could be nested in any amount of xrefs I'm a bit wary about removing it. (I think that gave me reload errors.)