"(((-1 . <Entity name: 7ef08940>) (0 . LWPOLYLINE) (330 . <Entity name:
7ef05cf8>) (5 . 1368) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 .
AcDbPolyline) (90 . 7) (70 . 0) (43 . 0.0) (38 . 0.0) (39 . 0.0) (10 -49522.9
14762.6) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 8723.02 44922.5) (40 .
0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 39807.6 1190.63) (40 . 0.0) (41 . 0.0)
(42 . 0.0) (91 . 0) (10 95035.6 21096.2) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 .
0) (10 110729.0 49748.1) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 134872.0
18080.2) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 141512.0 -22937.3) (40 .
0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (210 0.0 0.0 1.0)))"
(defun obj->str (ent / relst mid)
(setq relst (list -1 330 330 5 100 100 102 102 410))
(setq mid (print ent))
(foreach num relst
(progn
(setq mid (vl-remove (assoc num mid) mid))
)
)
(vl-prin1-to-string mid)
)
(defun obj->str->fn (ent fn / f_test str)
(setq f_test (open fn "a"))
(setq str (obj->str ent))
(prin1 str f_test)
(close f_test)
)
(defun str->obj (str)
(entmake (string->entlst str))
)
(defun string->entlst (str / b l res)
(setq l (string->strlst str ")"))
(foreach a l
(cond ((wcmatch a "*\"*")
(setq b (string->strlst
(vl-string-translate
"\""
" "
(vl-string-trim "(" (vl-string-trim " " a)))
"."))
(setq res (cons (cons (eval (read (car b)))
(vl-string-trim " " (cadr b)))
res)))
((setq res (cons (read (strcat a ")")) res)))))
(reverse res))
(defun string->strlst (str del / lst a s1 cha pos i)
(setq s1 ""
i 0
a (ascii del)
)
(while (setq pos (vl-string-position a str i))
(setq s1 (substr str (1+ i) (- pos i)))
(if (/= s1 "")
(setq lst (cons s1 lst))
)
(setq i (1+ pos))
)
(setq s1 (substr str (1+ i)))
(if (/= s1 "")
(setq lst (cons s1 lst))
)
(reverse lst)
)
Better back up a step. If this is from a (princ...) to the command line, those wrapping double-quotes DON'T ACTUALLY EXIST. Moreover, the (entget...) function which generates this type of return doesn't return a string value, it returns a list of dotted pairs.
Context is everything - a little more information would lead to a nicely curved garden path, rather than a cloverleaf-intersection. :wink:
Better back up a step. If this is from a (princ...) to the command line, those wrapping double-quotes DON'T ACTUALLY EXIST. Moreover, the (entget...) function which generates this type of return doesn't return a string value, it returns a list of dotted pairs.
Context is everything - a little more information would lead to a nicely curved garden path, rather than a cloverleaf-intersection. :wink:
You would use the read function, however, since the DXF data has been converted to a string, the entity name pointers (e.g. <Entity name: 7ef08940>) will no longer be accessible and will cause the read function to error since they will be interpreted as two separate symbols which form an invalid dotted pair structure.
For example, the dotted pairs containing entity names would be equivalent to attempting to convert:
$ (read "((-1 . a b))")
; error: extra cdrs in dotted pair on input
Since the two parts of the entity name pointer would be interpreted as two individual symbols:
(-1 . <Entity name: 7ef08940>)
And a dotted pair may only consist of two atoms, no more, no less.
it looks as if the OP used vl-princ-to-string, notice how the second element of DXF 0 or 8 or 410 looses its double quotes on the string on the first post? --->(0 . LWPOLYLINE)
with princ ---> (0 . "LWPOLYLINE")
with vl-prin1-to-string -- > (0 . \"LWPOLYLINE\")
Now just for the fun of it. go ahead and convert the string [just as it is now] to a usable data :)
EDIT: Yes, its a challenge :D
Code - Auto/Visual Lisp: [Select]
(entmakex (rts postedstring))
Usable: --->>> Excludes DXF 0 5 330 <<<---but you guys already know that.
Do you have control over how they are saved to a file ??
You cant re-use handles
You can't re-use ObjectID's
You need a way of asserting that Table objects exist in the target drawing ; ie layers, styles, linetypes etc, etc.
Hint:
Do you know what the acronym DXF stands for ??
Do you know the commands DXFOUT, DXFIN ??
Sounds to me as if you could achieve your target with blocks (simply archive the drawing at each report stage)
no code, no maintenance, ...
just name your 'saveas' using the 'stage' number/name/ID
....
(entmakex (rts postedstring))
Usable: --->>> Excludes DXF 0 5 330 <<<---but you guys already know that.
Now you have made it very difficult for me to take your challenge... that function did what I wanted!
I'm not trying to scare you off the project :)
as dgorsman noted early in the thread, knowing ALL the details is important.
I don't see why the concern about little disk space should stop the project.
It would be easier to cut and paste some entitys from a previous incarnation of the drawing that to write code to control it.
I don't understand exactly what you mean by 'stages' and notes.
In the past I have documented progress and recorded milestone events simply by archiving the drawing (ie save-As) and using a meaningful name for the document. Sometimes this happened several times a day.
It was a critical QA process when we were dealing with recording a drawing state prior to making design changes.
....Ideally I could then automatically revert the drawing to any revision....
....Ideally I could then automatically revert the drawing to any revision....
That would be neat huh? :-)
I was wondering, do you need to recreate it or compare it to an existing object or both?Better back up a step. If this is from a (princ...) to the command line, those wrapping double-quotes DON'T ACTUALLY EXIST. Moreover, the (entget...) function which generates this type of return doesn't return a string value, it returns a list of dotted pairs.
Context is everything - a little more information would lead to a nicely curved garden path, rather than a cloverleaf-intersection. :wink:
Hi there.
Sorry for the lack of context. I'm using princ to a txt file and then I'm using the read-line function to put the content to a variable, and what I posted is the result of the read-line to a variable.
What I'm trying to do is to save some objects info in a txt file so I can later "rebuild" them when I want.
Reading more of your post I would think you would need to create a revision copy each time you added a note.
Or was your intent to selectively recreate selected objects pertaining to that note only & keep the current DWG?
Dose Landlord want to protect dwg not to be regain by this way (write protect dwg into txt file , and then rebuild dwg )?
wow that's really nice! I already had thought about adding some kind of markers.there is no way to entmake dynamic block or create them with vlisp.
Yeah I guess those entities you are talking about are the things that will become problems for me because I don't know about them.
In my ignorance I intended to record each entity with the result I get from creating a selection set and using (entget (ssname x index))
Are you saying that with this I don't get all the info I need to draw every entity I need?
hehe.. I guess there goes my ideia! thank you for your inputthere is something what might work but...dwg will be huge and heavy.
How about WBLOCK objects and forget about the text file for entities.wow that's really nice! I already had thought about adding some kind of markers.there is no way to entmake dynamic block or create them with vlisp.
Yeah I guess those entities you are talking about are the things that will become problems for me because I don't know about them.
In my ignorance I intended to record each entity with the result I get from creating a selection set and using (entget (ssname x index))
Are you saying that with this I don't get all the info I need to draw every entity I need?
some entities will be very very, hard to recreate 100%.
k.
yes. but this is addittional files on hard drive. Brick_top don't want to do this if i understandHow about WBLOCK objects and forget about the text file for entities.wow that's really nice! I already had thought about adding some kind of markers.there is no way to entmake dynamic block or create them with vlisp.
Yeah I guess those entities you are talking about are the things that will become problems for me because I don't know about them.
In my ignorance I intended to record each entity with the result I get from creating a selection set and using (entget (ssname x index))
Are you saying that with this I don't get all the info I need to draw every entity I need?
some entities will be very very, hard to recreate 100%.
k.
hehe.. I guess there goes my ideia! thank you for your inputthere is something what might work but...dwg will be huge and heavy.
1. create a copy of ALL objects
2. when you create your Note1 point go thru all copies and add Xdata (Note1).
3. rename (with copy) all blocks to name_Note1
4. when add another NoteX follow step 1-3
using visibility properties show/hide notes with xdata
kruuger
hi Brick_top
that's very crazy idea. problem is, how do you want to recreate deleted object like: blocks (dynamic block), formated mtext, splines...more complex objects. this will work rather with simple shape like lines.
Wow you guys are too good :omost of objects but not all.
Do you mean you can create any object with that routine?
At least there is hope it seems :)
Wow you guys are too good :omost of objects but not all.
Do you mean you can create any object with that routine?
At least there is hope it seems :)
k.
for sure dynamic block. maybe multileaderWow you guys are too good :omost of objects but not all.
Do you mean you can create any object with that routine?
At least there is hope it seems :)
k.
Can you tell me how do I learn which objects are those?
Brick_top ,
What is the actual purpose of saving this data ??
I wanted a way to have a drawing revert to several versions defined by me in another routine I have to save development notes. Withouth having severall full versions of the drawing saved in disk.
What do you intend doing with these saved entities ??
I would like to say that each version of a drawing is related to a note I made and if I want I can have the drawing revert to that state
How often do you want to save them ?
As often as some revision is made to the project
How often will you want to restote them ?
As often as requested by anyone who wants to see another version of a drawing.
Will any restore be a full restore or partial ?
I don't think there will be a full restore, if it happened it would be extremely rare
How many people in your group will be writing data ?
I'll be the only one writing data
Will you me writing from one model/control drawing or from several ?
I don't know if I understand this question correctly, but every entity would only be reverted to its original creation drawing.
How many drawings in the project ?
This would be only to work in one drawing at a time, to show its several versions. Every drawing would have its own notes and versions saved to its own saved versions
This might seem like a lot of questions, but these are things that will govern your best solution design.
Personally I think you will be best served doing a Wblock of selective DXFOut of the relevent entities ... but that belief may change depending on your intent.
Regards
This is my ideia of how it could work?
With each Note I would have to save to xrecord which version is currently in use and which are the entities that it contains.
For Example:
Note 2 Is composed by entities number x to x from note 1 and entities number x to x from note 2. I guess I would also have to keep adding to every note which entities are to be deleted.
because I know which version is currently in use I know what entities are already drawn and which are to be deleted.
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
When creating Notes and defining what entities belong to which version:
Note 1 - Would save a txt file for Note 1 with the numbered entities from Note 1 and save to xrecord that version from note 1 is in use and contains entities from number x to x from note 1.
Note 2 - For Note 2 I would compare every entity in the drawing against the ones that are saved in the txt from Note 1. I would then save to note 2 the new entities that are to be drawn. I will save to xrecord that Note 2 contains entities number x to x from Note 1 and number x to x from Note 2. I would also save the entities that are to be deleted from Note 1.
At this time I realize that acoording to which version currently in use and the one I intend to draw I must also save what entities are to be deleted according to the version currently in use.
Note 3 - Would have to compare the existing entities against Notes 1 and 2 to check which ones are to be drawn and deleted.
As of now I'm not thinking of any other problem that may arise... But I guess I'm sure there could be plenty.
It does sound like a big job. Though it might not be entirely impossible. The point about which codes to save or not, is not an easy one to answer, especially not in the case you're referring to:
I.e. you want a record of created, modified and/or erased entities, to allow a persistent partial-undo to be performed to any one of the variants?
If that's the case, then the "simplest" solution would be using a wblock (as someone's suggested previously), actually I'd go this route since IMO it's also the "best" solution. Basically, you'd select the object(s) and wblock selected to a new filename (you can calculate such name from something like the current date/time). Then if you need any further data for such (e.g. who performed the change, or any comments made for such), that can be saved into a TXT file with the same name, or you can add it as DWG propery into the WBlocked DWG file through ObjectDBX. All this can quite easily be automated through lisp (both the WBlocked DWG and the TXT). Not to mention, the wblock would handle the "What codes to save out" for you, actually DXFOut would do the same, but if you're doing it RAW in lisp to a txt file - you'd need to figure these out through trial-n-error. Not to mention: those ENames (which can't be read back) still needs to be saved out somehow - they refer to stuff like linked entities / dictionaries / object data / etc. So if you leave such out, you won't be able to return to a exact state for that entity - it might have "lost" some info in such process (this is why I say it would be trial-n-error).
If you're really pressed on disc space, then saving only the actually needed data into a TXT file "might" help ... though I'm not sure it will actually be smaller than the WBlock in all instances. The txt file saved from lisp would be very similar in size to a DXF file (as done through the SaveAs / DXFOut command) - at least if you save all the relevant data such as Layers/Styles/Blocks/Dictionaries/XData/etc. The reason I'm saying this is the DWG file created using WBlock is a normal Binary DWG file, and the newer ACads (I think since 2005) uses a form of compression (similar to ZIP) to reduce the filesize even further, the DXF/TXT on the other hand is very wasteful on space (e.g. in the binary it might use something like 2 bytes to store an integer code for what type of entity it is; but in DXF the entire Entity Name needs to be saved, one byte per letter - not to mention some form of stating what this portion of the file relates to). So even for the possible space-saving by omitting unneeded data, I'd think twice about going this route: lots of work for possibly even larger files.
If you really want it to be as small as possible, then you might rather want to generate a binary file of your own design. And in such case you might have to look into using DotNet (or at the very least some ActiveX streaming library through Visual Lisp). In which case you can even use some compression libraries to make that binary file even smaller than the DWG could possibly be. This I'd go for only as an extreme last resort - if you've got this type of problem with size, then you need to look elsewhere for easier / better / cheaper solutions like buying a NAS box with 16TB of storage :lmao:
I wouldn't like to use an external application to do this?to wrote good compare program would be another problem.
Here is a typical file of a project, I guess it is badly organized.
there is something what might work but...dwg will be huge and heavy.
1. create a copy of ALL objects
2. when you create your Note1 point go thru all copies and add Xdata (Note1).
3. rename (with copy) all blocks to name_Note1
4. when add another NoteX follow step 1-3
using visibility properties show/hide notes with xdata
kruuger
You mean this one right?no. i want use object visibility, dxf code 60. try attached program - HIDthere is something what might work but...dwg will be huge and heavy.
1. create a copy of ALL objects
2. when you create your Note1 point go thru all copies and add Xdata (Note1).
3. rename (with copy) all blocks to name_Note1
4. when add another NoteX follow step 1-3
using visibility properties show/hide notes with xdata
kruuger
When you say visibility properties you mean layer visibility right?
Problem might be that many times the projects suffer very small changes and for any change I would have a complete copy of the drawing. In case I understood your ideia.ehh, yes. everywhere problems, problems, problems...
You mean this one right?no. i want use object visibility, dxf code 60. try attached program - HIDthere is something what might work but...dwg will be huge and heavy.
1. create a copy of ALL objects
2. when you create your Note1 point go thru all copies and add Xdata (Note1).
3. rename (with copy) all blocks to name_Note1
4. when add another NoteX follow step 1-3
using visibility properties show/hide notes with xdata
kruuger
When you say visibility properties you mean layer visibility right?Problem might be that many times the projects suffer very small changes and for any change I would have a complete copy of the drawing. In case I understood your ideia.ehh, yes. everywhere problems, problems, problems...
so combination of wblock and visibility:
- each note create "snapshot" of your dwg (separate file - wblock)
- when you back to previous note the whole drawing will be "turned off" (using visibility)
- temporary rename all blocks name
- then program will attach required file as an xref or insert as block
- back to latest version will detach all files (delete blocks), unrename blocks, turn on object
kruuger
hi Brick_top
here is very rough sketch of what i describe
1. extract Note folder to drive D:
2. open latest.dwg
3. load lsp
4. type REC
5. select required Note
6. one xref overlay above another. it shouldn't be like that but i have a problem with refreshing screen when dcl is open
7. after cancel latest view is restored
kruuger
Unfortunately this makes me realize how little I know about this... there is so much I don't understand in your routine that it hurts.there are a lot of library function. probably can be squeeze a little without them.
edit - by the way i don't find it necessary to change between versions while the routine is running. Only one optional rebuild per run is enough.yes, but i have a problem with refresh xref, when detach-attach. anyone have solution how to refresh view when dcl is open? looks like redraw not working
Love the way you create the dcl without a separate file :o Is there any problem with that approach?no. many user do this here. you can very easy create multi-language file.
(setq ent (car (entsel "Pick a block: ")))
(while
(/= (cdr (assoc 0 (setq elst (entget (setq ent (entnext ent)))))) "SEQEND")
(setq entlst (append elst entlst))
);while
; =========================================================================================== ;
; Lista obiektow w definicji bloku / List of objects in block definition ;
; Name [STR] - nazwa bloku / block name ;
; Entity [STR] - nazwa entycji / entity name ;
; ------------------------------------------------------------------------------------------- ;
; (cd:BLK_GetEntity "*Model_space" nil), (cd:BLK_GetEntity "NAZWA" "*LINE") ;
; =========================================================================================== ;
(defun cd:BLK_GetEntity (Name Entity / en dt res)
(setq en (tblobjname "BLOCK" Name))
(while
(and
en
(setq en (entnext en))
(setq dt (entget en))
(/= "ENDBLK" (cdr (assoc 0 dt)))
)
(if
(if Entity
(wcmatch (cdr (assoc 0 dt)) (strcase Entity))
(cdr (assoc 0 dt))
)
(setq res
(cons
(cdr (assoc -1 dt))
res
)
)
)
)
(reverse res)
)
kruugerEntity [STR] - nazwa entycji / entity name
Thank you for answering again kruuger.second argument as nil and you got all objects
but i'm really sorry to say that I think I might not be using your routine correctly.
what do you mean by this?QuoteEntity [STR] - nazwa entycji / entity name
edit - now I understand.. and it works! I was thinking it would return every entity in a block and not only one type that I might choose.
I would prefer for it to create a list of every entity in the block, I'll see if I'm able to modify your code.
Many thinks sir!
hi Brick_top
here is very rough sketch of what i describe
1. extract Note folder to drive D:
2. open latest.dwg
3. load lsp
4. type REC
5. select required Note
6. one xref overlay above another. it shouldn't be like that but i have a problem with refreshing screen when dcl is open7. after cancel latest view is restored
kruuger
( T
(setq preview 2)
(while (>= preview 2)
(new_dialog "StdListDialog" dc ""
(cond
( *cd-TempDlgPosition* )
( (quote (-1 -1)) )
)
)
(if settings (restore_dialog_settings_defun))
(setq preview (start_dialog))
"(setq settings (dialog_save_settings_defun))(done_dialog 4)"
(cond
((= 4 preview)
(previewMyChanges_defun)
)
);cond
);while preview >=2 ;cycles back to our dialog
...
(defun _XrefNote (Val / xr)
(setq xr (kr:BLK_AttachXref "d:\\Note" Val '(0 0 0) 1 1 1 0 nil))
(vla-regen (vla-get-ActiveDocument (vlax-get-acad-object)) acActiveViewport)
(if (/= Val fl)
...