- UID
- 517
- 积分
- 935
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-1-14
- 最后登录
- 1970-1-1
|
发表于 2003-11-11 13:03:26
|
显示全部楼层
;;下面這堆誰看懂再寫些心得出來好嗎?

- ;|am writing a lisp routine that help creating a 3d model
- from a 2d plan cutting windows doors, etc..... extrude the walls
- and then set an axonometric view look for the doors and windows
- ask for some points elev (if window) height etc. then the program
- will cut the opening and draw the 3d window
- I need to filter only the solid wall in front of me
- example: |;
- ;|setq pt1 (getpoint "\nleft Corner inside 2d window:"))
- from pt1 i want to extract the solid wall in front of me
- first problem is if your draworder is putting the solid on
- top of the window line than your entget will show gibberish data.some thing like this:
- ):-+:' {rn {fj {fi |") (1 . ",+->687+r<*-): {rn ninqlggiofjjlfmnik
- nkqkkgghnljlgjng o o o n V V |") (1 . ":;8: {fh {gk {ki {jk {fg 90-(>-; |") (1
- . "/061+ {rn ninqlggiofjjlfmnik nkqkkgghnljlgjng nkk |") (1 . "/061+ {rn
- ninqlggiofjjlfmnik gqkkgghnljlgjnhfff nkk |") (1 . "-:9@)+r:&:r>++-6= {rn {rn
- {jo {ln {l {k |") (1 . "92:,7r:&:r>++-6= {rn {ff {rn {jn |") (1 .
- "/3>1:r,*-9><: {rn ninqlggiofjjlfmnik nkqkkgghnljlgjng nkk o o n n o o
- 90-(>-;@) V V V V |") (1 . "<0:;8: {rn {ik {noo {if {fj 90
- am not gonna paste the whole thing it will take a long space.
- need to control the selection when i need to select the lines and
- when i need to select the solid wall to subtract for example.
- (ssget pt1 '((0 . "solid")))|;
- ;;-------------------------------------------------------------------
- ;;; go to spatial technolgies web site and get the sat guide book itdescribes
- ;;; the structure of the file, autocad stores 3dsolid data in the same format
- ;;; (entget) returns the entity data and the group 1 codes reflect each line in
- ;;; the sat file. the strings are scrambled and can be translated to readable
- ;;; text with this function:
- ;;; s = string to be translated to or from readable format or autocad entity format
- (defun TRACIS (S / N L)
- (setq N "")
- (while (> (strlen S) 0)
- (setq
- L (substr S 1 1)
- S (substr S 2)
- N (strcat N
- (if (= " " L)
- ""
- (chr (- 79 (- (ascii L) 80)))
- )
- )
- )
- )
- )
- (defun C:SACIS (/ ENT E_DATA)
- (if (setq ENT (entsel "Seleziona solido Acis: "))
- (progn
- (terpri)
- (setq E_DATA (entget (car ENT)))
- (foreach DXF_1 (ALE_MASSOC 1 E_DATA)
- (princ (TRACIS DXF_1))
- (terpri)
- )
- )
- )
- (princ)
- )
- ;;; i have a small library of lisp acis functions to extract info from solids,
- ;;; generate profiles along alignments, create surface models, it can be done
- ;;; with autolisp
- ;|
- Eric;
- In R2002: A quick non-programming way to get POINTs from ACIS objects is
- to create an xml file of the geometry using WBLOCK or EXPORT, and read the
- xyz entries for the "point" entities directly from the xml text file.
- eg. "point $-1 0 3 0 #" --------> coordinates are '(0 3 0)
- For non-R2002, you can get a start by using Kailas Dage's decrypting
- code which follows.
- |;
- ;;;From: Kailas Dhage (kailas@uts.com)
- ;;;Subject: Re: ACIS info
- ;;;Newsgroups: autodesk.autocad.customization
- ;;;Date: 1999/05/10
- ;;;
- ;;;Hi
- ;;;Please have look at code given below:
- ;;;; Acis decode string
- (defun ACISDECODE (ST / LN N C ST1)
- (setq ST1 ""
- N (strlen ST)
- )
- (while (> N 0)
- (setq C (ascii (substr ST N 1)))
- (setq ST1 (strcat (cond ((= C 32) " ")
- ((= C 86) "I")
- ((chr (boole 6 C 95)))
- )
- ST1
- )
- )
- (setq N (1- N))
- )
- ST1
- )
- ;;; Acis decode entity
- (defun ACISDECODEENT (ENT)
- (foreach @@ ENT
- (if (= (car @@) 1)
- (setq ENT (subst (cons 1 (ACISDECODE (cdr @@))) @@ ENT))
- )
- )
- ENT
- )
- ;;; Display items
- (defun ACISWHAT (ENT TP)
- (setq TMP ())
- (foreach @@ ENT
- (if (and (equal (car @@) 1) (wcmatch (cdr @@) (strcat TP "*")))
- (setq TMP (cons @@ TMP))
- )
- )
- (reverse TMP)
- )
- ;;; GetACISDataonly
- (defun GETACISDATAONLY (ENT)
- (setq TMP ())
- (foreach @@ ENT
- (if (equal (car @@) 1)
- (setq TMP (cons @@ TMP))
- )
- )
- (setq TMP (reverse TMP))
- (setq TMP1 (car TMP)
- TMP (cdr TMP)
- TMP (cdr TMP)
- TMP (cdr TMP)
- )
- (cons TMP1 TMP)
- )
- ;;; Main Routine
- (defun C:TEST ()
- (setq ORENT (entget (car (entsel "\nSelect 3d Solid entity: "))))
- (setq DEENT (ACISDECODEENT ORENT))
- (setq ACENT (GETACISDATAONLY DEENT))
- (princ "\nOrEnt: ")
- ;(princ ORENT)
- (princ "\nDeEnt: ")
- (princ DEENT)
- (princ "\nacEnt: ")
- (princ ACENT)
- (princ)
- )
- ;;;
- ;;;Cheers !!!
- ;;;
- ;;;Kailas Dhage
- ;;;UTS(i) India
- ;;Actually, ACISdecode function is by Owen Wengerd
- ;;and it appears EXACTLY as in the code you mention,
- ;;only 2.5 years _before_ it, as cited in the article
- ;;[[--------------------------------
- ;;Newsgroups: comp.cad.autocad
- ;;Subject: Re: R13 3D Solids
- ;;Date: Fri, 08 Nov 1996 14:55:28 GMT
- ;;owenw@manusoft.com (Owen Wengerd) has posted
- ;;this version on c.c.a. :
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (defun ACISDECODE (ST / LN N C ST1)
- (setq ST1 ""
- N (strlen ST)
- )
- (while (> N 0)
- (setq C (ascii (substr ST N 1)))
- (setq ST1
- (strcat
- (cond
- ((= C 32) " ")
- ((= C 86) "I")
- ((chr (boole 6 C 95)))
- )
- ST1
- )
- )
- (setq N (1- N))
- )
- ST1
- )
- ;;--------------------------------]]
- ;;The real question is, what to do with the decrypted solid data?
- ;;Points are trivial to see, but how to get "faces" ? All I see is
- ;;some indices with no apparent meaning.
- ;;Does someone know how this data can be interpreted? Joe,
- ;;you mention you can recreate the edges. Could you explain _how_?
- ;;--
- ;;Vlad [url]http://vnestr.tripod.com/[/url]
- ;;--
- (defun C:SOLID-OUT (/ E D FD)
- (cond
- ((and
- (setq E (car (entsel)))
- (setq D (entget E))
- (= "3DSOLID" (cdr (assoc 0 D)))
- (setq FD (open "solid.out" "w"))
- )
- (foreach G D
- (and (= 1 (car G))
- (princ (ACISDECODE (cdr G)) FD)
- (princ "\n" FD)
- )
- )
- (close FD)
- (findfile "solid.out")
- )
- )
- )
- ;|
- From: "Joe Funk" <joefunk50@shaw.ca>
- Subject: Re: find vertex data of a solid
- Date: Saturday, February 09, 2002 6:22 PM
- Vladimir;
- Thanks for pointing out that Owen was the author. He's good at
- deciphering things, isn't he? Kailas definitely should have attributed
- the code.
- Yikes! re. recreating the edges of an ACIS object, I'm not sure
- how detailed to get, for fear of being boring or confusing (or worse
- - revealing my ignorance). You likely already know some or most of this.
- I downloaded from Spatial Technologies the pdf docs which describe the
- ACIS SAT file Format. Chapter 2 gives details, of which I understand a
- small portion.
- Once the AutoCAD dxf listing for an ACIS object, say a BOX, is
- translated into readable strings using Owen's code, the new record
- shows items like "face", "edge", "vertex", and "point". Each item is
- indexed to show its relationship to other items in the ACIS object.
- The indices are only implied, by the order of the objects in the record. To
- make it easier for my LISP to work with, I re-write the record again
- as explicitly indexed lists.
- In the record, a header takes up the first 3 lines. The indexing starts
- with the first ACIS object, on line 4, so a "face" on line 6 of the record
- has index 3.
- The Owen-translated line looks like:
- "face $-1 $4 $5 $2 $-1 $6 forward single #"
- which I change to this indexed list:
- (3 . "face $-1 $4 $5 $2 $-1 $6 forward single #")
- Since a "face" has "edge"s and "point"s, and doesn't require higher math
- to trace out, it's maybe a good object to talk about. Here's how I pursue a
- face by following its indices downward in the record to get its 3 or 4 3-D
- points, in this case 4, in proper order for drawing a 3DFACE.
- Path to follow to get a face's coordinates:
- face
- |
- --> loop
- |
- --> coedge (main)
- --> coedge
- --> edge --> 2 vertices -->2 points * second pair points
- --> coedge
- --> edge --> 2 vertices--> 2 points * third pair points
- --> coedge [ignore]
- --> edge --> 2 vertices --> 2 points * first pair points
- The "loop" points to a coedge, whose own "edge" is the side to
- be drawn first. The order of a coedge's endpoints = the order
- in which they appear in the corresponding edge record.
- coedge -> edge -> 2 "vertex"es -> 2 points (in drawing order)
- So ... starting with a "face" in the record ....
- (3 . "face $-1 $4 $5 $2 $-1 $6 forward single #")
- ;;------ loop5---------------------------
- You can identify which type of object a value is for, by the order of
- the entries in the string. The fourth value in this string holds the index
- for the line defining the face's "loop". (It's in the pdf's.) Go to that
- line (indexed here by 5) to find the "loop":
- (5 . "loop $-1 $-1 $10 $3 #")
- ;;-------coedge10------------------------
- Go to line indexed by 10 to find the main co-edge:
- (10 . "coedge $-1 $15 $16 $17 $18 forward $5 $-1 #")
- ;;coedge15, coedge16, coedge17, edge18-------
- Track down the 4 coedges 15, 16, 17, and 18. For each
- coedge, get:
- - its "edge"
- - the 2 vertices of the edge
- - and the 2 "point"s (xyz values) for these vertices
- (15 . "coedge $-1 $27 $10 $28 $29 forward $5 $-1 #")
- ;;--------------------edge29-----------------
- (29 . "edge $-1 $36 $56 $28 $57 forward #")
- ;;---vertex36, vertex56--------------
- (36 . "vertex $-1 $18 $64 #")
- ;;-------point64-------
- (64 . "point $-1 5 3 2 #") 2
- (56 . "vertex $-1 $29 $77 #")
- ;;-------point77-------
- (77 . "point $-1 0 3 2 #") 3
- (16 . "coedge $-1 $10 $27 $30 $31 forward $5 $-1 #")
- ;;--------------edge31-----------------------
- (31 . "edge $-1 $59 $35 $30 $60 forward #")
- ;;---vertex59, vertex35--------------
- (59 . "vertex $-1 $53 $78 #")
- ;;-------point78-------
- (78 . "point $-1 0 0 2 #") 4
- (35 . "vertex $-1 $18 $63 #")
- ;;-------point63-------
- (63 . "point $-1 5 0 2 #") 2
- (17 . "coedge $-1 $32 $33 $10 $18 reversed $34 $-1 #")
- ;;-------------edge18--------------------------
- (18 . "edge $-1 $35 $36 $17 $37 forward #")
- ;;-----vertex35, vertex36------------
- (35 . "vertex $-1 $18 $63 #")
- ;;-------point63-------
- (63 . "point $-1 5 0 2 #") 1
- (36 . "vertex $-1 $18 $64 #")
- ;;-------point64-------
- (64 . "point $-1 5 3 2 #") 2
- Since the 2nd pt of edge29 /= 1st pt of edge31, this is a 4-sided
- face, drawn p63 -> p64 -> p77 -> 78.
- ;;;============================================
- That's a general description of how to get the points to re-create
- a face. It requires no math, just an understandingf of the SAT format.
- but ...
- For "curve"s and "surface"s, the ACIS record gives B-Spline
- info, for which matrix manipulation becomes necessary (or at least
- very handy).
- To date, I've been able to partially re-create the shape of what was
- originally an AutoCAD spline-fit 2-D polyline, from which a REGION
- was created. I'm missing some parts to the puzzle:
- 1. The ACIS record:
- - only seems to give 3 control points, whereas I think the
- B-Spline equations need 4. I already knew what the 4th point
- was because I created the object in the first place, so I
- plugged it into the matrix and got the points defining the
- "first quarter" of the curve
- 2. The math:
- - even given enough points to feed to the matrix, I only get 1/4 of
- the curve
- - apparently need to use a loop, feeding the 4 points to the
- matrix 4 times, starting with a different point each time
- Vladimir, I used some matrix functions I found in your discussions
- with ibro vehabovic about Bezier curves ... perhaps you remember
- some of these functions:
- mat*scalar
- mat-trans
- vec*vec
- mat*vec
- Here's the B-Spline equation I used:
- To calculate a point on the curve, given 4 control points Xi:
- p(t)= MTX-T * MTX-BASIS * MTX-PTS
- =>
- [ t^3 t^2 t 1] [-0.1667 0.5 -0.5 0.1667] [Xi-1 ]
- [ 0.5 -1 0.5 0 ] [Xi ]
- [ -0.5 0 0.5 0 ] [Xi+1]
- [0.1667 0.6667 0.1667 0] [Xi+2]
- ;;;the Basis Matrix is rounded in that example, better use:
- ;;;"True" Basis Matrix for b-spline:
- ;;;| -1 3 -3 1 |
- ;;;| 3 -6 3 0 | 1
- ;;;| -3 0 3 0 | ---
- ;;;| 1 4 1 0 | 6
- If you have any suggestions, I'd be glad to hear them. I suppose this
- should be kept discrete, in case AutoDesk or Spatial feels that we're
- prying. *>) Just joking - I've so far detected no bad vibes from them.
- Joe
- "Track down the 4 coedges 15, 16, 17, and 18."
- should read
- "Track down the 3 coedges 15, 16, 17, and the edge 18."
- Joe
- Reini Urban has an example of decoding a REGION in the topic
- [28] "How to decode ACIS internal geometry with Lisp?"
- in his FAQ at [url]http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.2[/url]
- I've been fiddling with decoding ACIS objects when I have time. So far I
- can re-create straight edges and simple (2D) spline boundaries, but the code
- isn't dependable yet. Some linear algebra is required. I failed linear
- algebra.8>\|;
|
|