Antonella,
these are all my notes about Acis.
HTH
Marco
P.S.: are you from Italy?
--
________________________________________________
Marc'Antonio Alessi (TV) Italy
(strcat "NOT a " (substr (ver) 8 4) " guru.")
O.S. = XP Pro 2002 Ita - Sp.1
AutoCAD = 2004 Ita - Sp.1a
________________________________________________
;;; go to spatial technolgies web site and get the sat guide book it
describes
;;; 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 http://vnestr.tripod.com/
--
(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"
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 http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.2
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>\
Joe