Author Topic: Displacement in converted 3dSolids  (Read 2631 times)

0 Members and 1 Guest are viewing this topic.

S.Langhammer

  • Guest
Displacement in converted 3dSolids
« on: March 07, 2014, 07:54:52 AM »
First of all: the shwon graphic comes from a DWG available here:
http://www.waldmann.de/waldmann-architektur/home/home/service/3d-daten_pcon_planner.de.html
It's the "ATARO 4 x Γ".

I'm using a script to convert any given dwg or dxf file to a txt file, only containing the necessary drawing information. I skipp stuff like line types, viewports, lights, textures and so on.

Now the example file here consits among others of a few  3dSolids. In order to read those out correctly I need to convert them. Somewhere along the way, I catch a displacement in this function:

Code - Auto/Visual Lisp: [Select]
  1. (defun simplify ( chkBlk /
  2.                                                         ExplodeObject
  3.                                                         convertSpline
  4.                                                         convertSAT
  5.                                                        
  6.                                                         objType a b isSAT)     
  7. (defun ExplodeObject    (object
  8.                                                                 /       N_ExplodeCommandModelSpace
  9.                                                                         N_ExplodeCommandOther
  10.                                                                         N_ExplodeMethod
  11.                                                                        
  12.                                                                         modelSpaceObject ownerObject
  13.                                                 )
  14.  
  15.         (defun N_ExplodeCommandModelSpace (object)
  16.                 ; Use the explode command:
  17.                 (command "_.explode" (vlax-vla-object->ename object))
  18.                 (princ)
  19.         )
  20.  
  21.                 ;; The function uses the following variables from the main function:
  22.                 ;;   activeDocument
  23.                 ;;   modelSpaceObject
  24.                 ;;   ownerObject
  25.         (defun N_ExplodeCommandOther (object / lastEname newEnameList newObjectList tempObject)
  26.                 ; Store the ename of the last object in modelspace:
  27.                 (setq lastEname (entlast))
  28.                 ; Required for 'SEQEND situations':
  29.                 (while (entnext lastEname)
  30.                         (setq lastEname (entnext lastEname))
  31.                 )
  32.                 ; Make a temporary copy of the object from the block definition in modelspace:
  33.                 (setq tempObject
  34.                         (car
  35.                                 (vlax-invoke
  36.                                         activeDocument
  37.                                         'copyobjects
  38.                                         (list object)
  39.                                         modelSpaceObject
  40.                                 )
  41.                         )
  42.                 )
  43.                 ; Delete the object from the block definition:
  44.                 (vla-delete object)
  45.                 ; Use the explode command:
  46.                 (command "_.explode" (vlax-vla-object->ename tempObject))
  47.                 ; Get the enames of all new objects in modelspace:
  48.                 (while (setq lastEname (entnext lastEname))
  49.                         (setq newEnameList (cons lastEname newEnameList))
  50.                 )
  51.                 ; Copy the new objects to the block definition:
  52.                 (if newEnameList
  53.                         (setq newObjectList
  54.                                 (vlax-invoke
  55.                                         activeDocument
  56.                                         'copyobjects
  57.                                         (mapcar 'vlax-ename->vla-object newEnameList)
  58.                                         ownerObject
  59.                                 )
  60.                         )
  61.                 )
  62.                 ; Delete the new entities from modelspace:
  63.                 (mapcar 'entdel newEnameList)
  64.                 (princ)
  65.         )
  66.  
  67.         (defun N_ExplodeMethod (object / newObjectList)
  68.                 (setq newObjectList (vlax-invoke object 'explode))
  69.                 (vla-delete object)
  70.                 ; Return the new objects in the block definition:
  71.                 newObjectList
  72.         )
  73.         ;;; object to ename
  74.         (setq object (vlax-ename->vla-object object))  
  75.         (if (vlax-method-applicable-p object 'explode)
  76.                 (N_ExplodeMethod object)
  77.                 (progn
  78.                         ; Make sure that modelspace is current:
  79.                         (setvar 'tilemode 1)
  80.                         (setq modelSpaceObject  (vla-get-modelspace activeDocument)
  81.                                   ownerObject           (vla-objectidtoobject activeDocument (vla-get-ownerid object))
  82.                         )
  83.                         (if (not(wcmatch (strcase objType) safeObjects))
  84.                                 (if (= ownerObject modelSpaceObject)
  85.                                         (N_ExplodeCommandModelSpace object)
  86.                                         (N_ExplodeCommandOther      object)
  87.                                 )
  88.                         )
  89.                 )
  90.         )
  91.         (princ)
  92. )
  93. ;;;
  94. (defun convertSpline    (object
  95.                                                                 /       N_PEDITCommandModelSpace
  96.                                                                         N_PEDITCommandOther
  97.                                                                         modelSpaceObject ownerObject
  98.                                                 )
  99.  
  100.         (defun N_PEDITCommandModelSpace (object / lastEname)
  101.                 ; Use the PEDIT command:
  102.                 (command "_.PEDIT" (vlax-vla-object->ename object) "" "")
  103.                 ; Get the enames of all new objects in modelspace:
  104.                 (princ)
  105.         )
  106.         (defun N_PEDITCommandOther (object / lastEname newEnameList newObjectList tempObject)
  107.                 ;; The function uses the following variables from the main function:
  108.                 ;;   activeDocument
  109.                 ;;   modelSpaceObject
  110.                 ;;   ownerObject
  111.                 ; Store the ename of the last object in modelspace:
  112.                 (setq lastEname (entlast))
  113.                 ; Required for 'SEQEND situations':
  114.                 (while (entnext lastEname)
  115.                         (setq lastEname (entnext lastEname))
  116.                 )
  117.                 ; Make a temporary copy of the object from the block definition in modelspace:
  118.                 (setq tempObject
  119.                         (car
  120.                                 (vlax-invoke
  121.                                         activeDocument
  122.                                         'copyobjects
  123.                                         (list object)
  124.                                         modelSpaceObject
  125.                                 )
  126.                         )
  127.                 )
  128.                 ; Delete the object from the block definition:
  129.                 (vla-delete object)
  130.                 ; Use the PEDIT command:
  131.                 (command "_.PEDIT" (vlax-vla-object->ename object) "" "")
  132.                 ; Get the enames of all new objects in modelspace:
  133.                 (while (setq lastEname (entnext lastEname))
  134.                         (setq newEnameList (cons lastEname newEnameList))
  135.                 )
  136.                 ; Copy the new objects to the block definition:
  137.                 (if newEnameList
  138.                         (setq newObjectList
  139.                                 (vlax-invoke
  140.                                         activeDocument
  141.                                         'copyobjects
  142.                                         (mapcar 'vlax-ename->vla-object newEnameList)
  143.                                         ownerObject
  144.                                 )
  145.                         )
  146.                 )
  147.                 ; Delete the new entities from modelspace:
  148.                 (mapcar 'entdel newEnameList)
  149.                 (princ)
  150.         )
  151.         (setq object (vlax-ename->vla-object object))
  152.         ; Make sure that modelspace is current:
  153.         (setvar 'tilemode 1)
  154.         (setq modelSpaceObject  (vla-get-modelspace activeDocument)
  155.                   ownerObject           (vla-objectidtoobject activeDocument (vla-get-ownerid object))
  156.         )
  157.         (if (= ownerObject modelSpaceObject)
  158.                 (N_PEDITCommandModelSpace object)
  159.                 (N_PEDITCommandOther      object)
  160.         )
  161.         (princ)
  162. )
  163. ;;;
  164. (defun convertSAT       (en
  165.                                                         /       N_ConvertModelSpace
  166.                                                                 N_ConvertOther
  167.                                                                 modelSpaceObject ownerObject clipForm
  168.                                                 )
  169.  
  170.         (defun N_ConvertModelSpace (en)
  171.                 ; Use the ctrl-c-ctrl-p command:
  172.                 (command "._COPYBASE" '(0.0 0.0 0.0)  en "")
  173.                 (command "._PASTECLIP" '(0.0 0.0 0.0))
  174.                 (princ)
  175.         )
  176.        
  177.         (defun N_ConvertOther (object / lastEname newEnameList newObjectList tempObject)
  178.                 ;; The function uses the following variables from the main function:
  179.                 ;;   activeDocument
  180.                 ;;   modelSpaceObject
  181.                 ;;   ownerObject
  182.                 ; Store the ename of the last object in modelspace:
  183.                 (setq lastEname (entlast))
  184.                 ; Required for 'SEQEND situations':
  185.                 (while (entnext lastEname)
  186.                         (setq lastEname (entnext lastEname))
  187.                 )
  188.                 ; Make a temporary copy of the object from the block definition in modelspace:
  189.                 (setq tempObject
  190.                         (car
  191.                                 (vlax-invoke
  192.                                         activeDocument
  193.                                         'copyobjects
  194.                                         (list object)
  195.                                         modelSpaceObject
  196.                                 )
  197.                         )
  198.                 )
  199.                 ; Delete the object from the block definition:
  200.                 (vla-delete object)
  201.                 ; Use the ctrl-c-ctrl-p command:
  202.                 (command "._COPYCLIP" en "")
  203.                 (command "._PASTECLIP")
  204.                
  205.                 ; Get the enames of all new objects in modelspace:
  206.                 (while (setq lastEname (entnext lastEname))
  207.                         (setq newEnameList (cons lastEname newEnameList))
  208.                 )
  209.                 ; Copy the new objects to the block definition:
  210.                 (if newEnameList
  211.                         (setq newObjectList
  212.                                 (vlax-invoke
  213.                                         activeDocument
  214.                                         'copyobjects
  215.                                         (mapcar 'vlax-ename->vla-object newEnameList)
  216.                                         ownerObject
  217.                                 )
  218.                         )
  219.                 )
  220.                 ; Delete the new entities from modelspace:
  221.                 (mapcar 'entdel newEnameList)
  222.                 (princ)
  223.         )
  224.        
  225.         ; Make sure that modelspace is current:
  226.         (setvar 'tilemode 1)
  227.         ;;; save iriginal clipboard format and set it to 22
  228.         (setq clipForm (getvar "ClipBoardFormat"))
  229.         (setvar "ClipBoardFormat" 22)
  230.         (setq modelSpaceObject  (vla-get-modelspace activeDocument)
  231.                   ownerObject           (vla-objectidtoobject activeDocument (vla-get-ownerid (vlax-ename->vla-object en)))
  232.         )
  233.         (if (= ownerObject modelSpaceObject)
  234.                 (N_ConvertModelSpace en)
  235.                 (N_ConvertOther      (vlax-ename->vla-object en))
  236.         )
  237.         ;;; restore clopboard format
  238.         (setvar "ClipBoardFormat" clipForm)
  239.         (princ)
  240. )
  241. ;;;
  242.  
  243.         (setq objType "")
  244.         (foreach a (Blk_ENameLstNstd chkBlk)
  245.                 (setq isSAT 0)
  246.                 (foreach b (entget a)
  247.                         (if (= (car b) 100)(progn
  248.                                 (setq objType (cdr b))
  249.                                 (if (= objType "AcDbModelerGeometry") (setq isSAT 1))
  250.                         ))
  251.                 )
  252.                 (if (= isSAT 1)
  253.                         (vl-catch-all-apply 'convertSAT (list a))
  254.                 (progn
  255.                         (if (=(strcase objType) "ACDBSPLINE")
  256.                                 (vl-catch-all-apply 'convertSpline (list a))
  257.                         )
  258.                         (if     (not(wcmatch (strcase objType) safeObjects))
  259.                                 (vl-catch-all-apply 'ExplodeObject (list a))
  260.                         )
  261.                 ))
  262.         )
  263.         (princ)
  264. )
  265.  

I call it for every block, that possibly contains readable data.  The error must be somewhere around the "convertSAT" sub-function. I posted the entire function so you can get an idea about how it's called and with what variables.
My testing enviorment for my script is BricsCAD. I've got no access to AutoCAD but I've heared it has an actual lisp compiler with debug function. That could have saved me a lot of checking and reworking by now.

S.Langhammer

  • Guest
Re: Displacement in converted 3dSolids
« Reply #1 on: March 07, 2014, 08:03:42 AM »
Addition:
Just to see if it works, I exploded everything and the lamp looked fine in the end, so I assume the error must be somewhere in convertSAT->N_ConvertOther.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Displacement in converted 3dSolids
« Reply #2 on: March 07, 2014, 11:43:24 AM »
I suggest you look at lines 202 and 203:
1. Why are you not supplying coordinates? Compare lines 172 and 173.
2. You probably want to work on the tempObject and not on the en entity.

S.Langhammer

  • Guest
Re: Displacement in converted 3dSolids
« Reply #3 on: March 17, 2014, 04:40:51 AM »
I'm not supplieing coordinates in to make sure any displacement, that the object/entity might have is transported as well.
You were right about the en/tempObject part. I actually checked that on Friday two weeks ago. But that was close to quitting time and actually the last work day before my vacation and I didn't manage to replie until now.

I also don't exactly know what coordinates I should get. 3DSolids for example don't have anything like DXF-GroupCode 10,20,30. I can't get any coordinates by clicking anything. The script is ment to run unmonitored on a server.

Is there a way of reading the base point from a BODY, 3DSOLID or REGION automaticly?

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Displacement in converted 3dSolids
« Reply #4 on: March 17, 2014, 05:56:45 AM »
If you create a test function using the code from lines 202+203 you will find that the pasteclip command REQUIRES a point. If your code does not fail the BIG question is what point is being used?

General advice: Create more unnested subs and try to keep them short. That way your code will be easier to debug and maintain.

S.Langhammer

  • Guest
Re: Displacement in converted 3dSolids
« Reply #5 on: March 17, 2014, 06:08:36 AM »
As it seems, it takes 0.0,0.0,0.0 as default point, at least BricsCAD Does. I've taken advantage of this befor, when I had to gather some single DWGs to a block library-DWG.

My english isn't perfect so a tiny clarification would be nice: Do you mean by creating unnested subs for example instead of calling this code construction:

Code - Auto/Visual Lisp: [Select]
  1.                 (if newEnameList
  2.                         (setq newObjectList
  3.                                 (vlax-invoke
  4.                                         activeDocument
  5.                                         'copyobjects
  6.                                         (mapcar 'vlax-ename->vla-object newEnameList)
  7.                                         ownerObject
  8.                                 )
  9.                         )
  10.                 )
  11.  

Making a function, that contains it and call that function instead?

S.Langhammer

  • Guest
Re: Displacement in converted 3dSolids
« Reply #6 on: March 17, 2014, 08:18:45 AM »
I've found an other error. I called the function wrong. Now it's a complete riddle to me, how any 3D-data got extracted, since I don't read 3DSolids directly and there are no other 3dobjects with the given shapes....

S.Langhammer

  • Guest
Re: Displacement in converted 3dSolids
« Reply #7 on: March 17, 2014, 09:20:35 AM »
Ok I've tested it through a little.
It seems to work up until a certain point. At least The command line printed my marker, that theright function has been reached, but then I get this error line:
; error : Automation Error 80020009; [IAcadDocument] Error accessing [COPYOBJECTS] method. ErrIndex=0;

Now the code I suspect to produce the error is this:
Code - Auto/Visual Lisp: [Select]
  1.         (defun N_ConvertModelSpace (en / object)
  2.                 (princ "modelspace")
  3.                 (setq object    (vlax-ename->vla-object en))
  4.                 ; Use the ctrl-c-ctrl-p command:
  5.                 (if (= (vlax-method-applicable-p object 'COPYOBJECTS) T)(progn
  6.                         (command "._COPYBASE" '(0.0 0.0 0.0) object "")
  7.                         (command "._PASTECLIP" '(0.0 0.0 0.0))
  8.                 ))
  9.                 (princ)
  10.         )
  11.  

I actually check, if the object works with the copy function (at least that's how I understood the line (vlax-method-applicable-p object 'COPYOBJECTS) T)). It runs the copy command and I still get that error. Anyone any ideas? Maybe I just missunderstood something.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Displacement in converted 3dSolids
« Reply #8 on: March 18, 2014, 08:19:45 AM »
The code in lines 202 and 203 really is wrong. Try these functions, you will find that only c:test3 works properly:
Code: [Select]
(defun c:test ( / en)
  (setq en (car (entsel)))
  (command "._COPYCLIP" en "")
  (command "._PASTECLIP")
)

(defun c:test2 ( / en)
  (setq en (car (entsel)))
  (command "._COPYCLIP" en "")
  (command "._PASTECLIP" '(0.0 0.0 0.0))
)

(defun c:test3 ( / en)
  (setq en (car (entsel)))
  (command "._COPYBASE" '(0.0 0.0 0.0) en "")
  (command "._PASTECLIP" '(0.0 0.0 0.0))
)

You should go back to the previous version of (N_ConvertModelSpace). The version in your last post makes no sense:
1.
Code: [Select]
(= (vlax-method-applicable-p object 'COPYOBJECTS) T)Is the same as:
Code: [Select]
(vlax-method-applicable-p object 'COPYOBJECTS)2.
Code: [Select]
(command ...)Does not accept objects.
3.
The copyobject method and the copypaste command are different 'things'. Using (vlax-method-applicable-p) is useless.

Making a function, that contains it and call that function instead?
I may not have chosen that example. But the problem seems to be that you have created code with several levels of nested functions that cannot be tested independently from their parent functions. Which is why debugging is giving you so much trouble.

S.Langhammer

  • Guest
Re: Displacement in converted 3dSolids
« Reply #9 on: March 19, 2014, 05:06:18 AM »
You're right about the lines 202 and 203. I've found another error, basicly just a typo I didn't notice, which caused the parent function convertSAT never to be called at all. Which makes me wonder why I got any graphical  there at all in the exported data.

Thanks for the clarification at point 1, 2 and 3.

I also figured to call (entdel en) to delete the AcDbModelerGeometry entity after converting it so if I run through the same entity by any reason, It won't cause redundant data.

Also I needed to change something in the parentfunction simplify.

I think I made it work now. I'm testing it with new files, that didn't work and old ones that did to see If I find any errors I didn't notice or caused any new ones.

Just out of interrest, is there a way to determine if copypaste works for an entity?

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Displacement in converted 3dSolids
« Reply #10 on: March 19, 2014, 06:11:11 AM »
To test for the success of a paste operation you can simply look at the last entity before and after the operation. Here is how I would do it.

The example also shows what I mean by:
General advice: Create more unnested subs and try to keep them short. That way your code will be easier to debug and maintain.

Code - Auto/Visual Lisp: [Select]
  1. (defun EnameLastGet ( / ename)
  2.   (setq ename (entlast))
  3.   ; Required for 'SEQEND situations':
  4.   (while (entnext ename)
  5.     (setq ename (entnext ename))
  6.   )
  7.   ename
  8. )
  9.  
  10. ; The ename argument is the last ename before the new entities were added.
  11. (defun EnameListAddedAfterGet (ename / enameList)
  12.   (while (setq ename (entnext ename))
  13.     (setq enameList (cons ename enameList))
  14.   )
  15.   enameList
  16. )
  17.  
  18. ; (SimplifyClipBoard (car (entsel)) T 22)
  19. ; The clipBoardFormat argument can be nil.
  20. ; To handle the clipBoardFormat in case of errors improved error handling is actually required.
  21. (defun SimplifyClipBoard (ename deleteP clipBoardFormat / enameLast oldClipBoardFormat)
  22.   (if clipBoardFormat
  23.     (progn
  24.       (setq oldClipBoardFormat (getvar 'clipboardformat))
  25.       (setvar 'clipboardformat 22)
  26.     )
  27.   )
  28.   (setq enameLast (EnameLastGet))
  29.   (command "_.copybase" '(0.0 0.0 0.0) ename "")
  30.   (command "_.pasteclip" '(0.0 0.0 0.0))
  31.   (if deleteP (entdel ename))
  32.   (if clipBoardFormat
  33.     (setvar 'clipboardformat oldClipBoardFormat)
  34.   )
  35.   (EnameListAddedAfterGet enameLast) ; Returns a list of new enames or nil.
  36. )