1 |
greg |
1.1 |
A general scheme has been defined for writing translators from CAD |
2 |
|
|
files to Radiance. This scheme should be used by anyone who writes a |
3 |
|
|
new translator, since it is both useful and general. |
4 |
|
|
|
5 |
|
|
One of the biggest problems encountered when importing CAD descriptions |
6 |
|
|
to a lighting simulation (or any good rendering program) is assigning |
7 |
|
|
materials to the surface geometry. Even if the creator of the model |
8 |
|
|
has been careful to make 3d surfaces instead of points and lines, most |
9 |
|
|
people don't even think about what a surface is made of until they're |
10 |
|
|
all done. At that point, of course, it's too late. Even if the user |
11 |
|
|
does give a little thought to materials, most CAD systems only permit |
12 |
|
|
the assignment of a color index to each surface, which is a start but |
13 |
|
|
far short of the information needed to make a good simulation. |
14 |
|
|
|
15 |
|
|
There are only a few CAD systems that "do the right thing" and allow the |
16 |
|
|
user to assign material identifiers to objects and individual surfaces. |
17 |
|
|
Such a program, GDS for example, makes writing a translator almost |
18 |
|
|
trivial, since the material identifiers can refer back to a library of |
19 |
|
|
materials maintained by the user, or even imported from the CAD system. |
20 |
|
|
|
21 |
|
|
Most CAD programs, like AutoCAD or Architrion, don't really use the |
22 |
|
|
notion of materials in their models at all. Instead, they |
23 |
|
|
differentiate surfaces by layer, color, block name, and so forth, none |
24 |
|
|
of which clearly makes sense to use as a material identifier. Even if |
25 |
|
|
the user creates a model with an intent to perform lighting |
26 |
|
|
simulations, he or she has no way to assign materials directly to the |
27 |
|
|
objects in the model. |
28 |
|
|
|
29 |
|
|
The only general solution is to use every available piece of information |
30 |
|
|
from the CAD model to assign materials. We can do this by using a set |
31 |
|
|
of mapping rules, created somehow by the user. (We are working on |
32 |
|
|
a HyperCard interface for selecting materials that should be very nice |
33 |
|
|
if we ever finish it.) The mapping rules are an ordered list of |
34 |
|
|
materials and the conditions a surface must satisfy in order to have |
35 |
|
|
that material. |
36 |
|
|
|
37 |
|
|
For example, if we wanted all surfaces in the Block "thingy" with the |
38 |
|
|
Color 152 to use the material "wood", and all other surfaces to use the |
39 |
|
|
material "default", we would create the following mapping file: |
40 |
|
|
|
41 |
|
|
default ; |
42 |
|
|
wood (Block "thingy") (Color 152) ; |
43 |
|
|
|
44 |
|
|
All surfaces would satisfy the first set of conditions (which is empty), |
45 |
|
|
but only the surfaces in Block "thingy" with Color 152 would satisfy the |
46 |
|
|
second set of conditions. |
47 |
|
|
|
48 |
|
|
Each rule can have up to one condition per qualifier, and different |
49 |
|
|
translators will use different qualifiers. A qualifier is simply an |
50 |
|
|
attribute that can be used to distinguish surfaces, such as Color, |
51 |
|
|
Layer, Reference ID, etc. A condition is either a single value for a |
52 |
|
|
specific attribute, or an integer range of values. (Integer ranges are |
53 |
|
|
specified in brackets and separated by a colon, eg. [-15:27], and are |
54 |
|
|
always inclusive.) A semicolon is used to indicate the end of a rule, |
55 |
|
|
which can extend over several lines if necessary. |
56 |
|
|
|
57 |
|
|
The semantics of the rule are such that "and" is the implied conjunction |
58 |
|
|
between conditions. Thus, it makes no sense to have more than one |
59 |
|
|
condition in a rule for a given qualifier. If the user wants the same |
60 |
|
|
material to be used for surfaces that satisfy different conditions, |
61 |
|
|
they simply add more rules. For example, if the user also wanted |
62 |
|
|
surfaces in Block "yohey" with Colors between 50 and 100 to use "wood", |
63 |
|
|
they would add the following rule to the end of the example above: |
64 |
|
|
|
65 |
|
|
wood (Color [50:100]) (Block "yohey") ; |
66 |
|
|
|
67 |
|
|
Note that the order of conditions in a rule is irrelevant. However, |
68 |
|
|
the order of rules is very important, since the last rule satisfied |
69 |
|
|
determines which material a surface is assigned. |
70 |
|
|
|
71 |
|
|
By convention, the identifier "void" is used to delete unwanted |
72 |
|
|
surfaces. It is used in a rule as any other material, but it has the |
73 |
|
|
effect of excluding all matching surfaces from the translator output. |
74 |
|
|
For example, the following mapping would delete all surfaces in the |
75 |
|
|
Layer 2 except those with the color "beige", to which it would assign |
76 |
|
|
the material "beige_cloth", and all other surfaces would be "tacky": |
77 |
|
|
|
78 |
|
|
tacky ; |
79 |
|
|
void (Layer 2) ; |
80 |
|
|
beige_cloth (Layer 2) (Color "beige") ; |
81 |
|
|
|
82 |
|
|
Hopefully, the meaning of the mapping rules is now clear, so we can |
83 |
|
|
discuss ways to help the user create the mapping for a given model. |
84 |
|
|
|
85 |
|
|
A translator should provide at least two basic options. The first |
86 |
|
|
option, "-n", simply reads the CAD input file and creates a list of |
87 |
|
|
qualifiers and values that can be used to differentiate surfaces in the |
88 |
|
|
model. The output of the program with "-n" should be something like: |
89 |
|
|
|
90 |
|
|
filename "Example Input File" |
91 |
|
|
filetype "Architrion" |
92 |
|
|
qualifier Color begin |
93 |
|
|
35 |
94 |
|
|
[100:110] |
95 |
|
|
200 |
96 |
|
|
end |
97 |
|
|
qualifier RefId begin |
98 |
|
|
1103 |
99 |
|
|
[5306:5307] |
100 |
|
|
"BIG Things" |
101 |
|
|
"little Things" |
102 |
|
|
end |
103 |
|
|
EOF |
104 |
|
|
|
105 |
|
|
This information can be used either by the user or by a program such as |
106 |
|
|
HyperCard to create the rules for assigning materials to surfaces in |
107 |
|
|
the file. (The "EOF" is literally there, since HyperCard has trouble |
108 |
|
|
detecting the end of file.) |
109 |
|
|
|
110 |
|
|
The second option, "-m mapfile" is used to specify the mapping file to |
111 |
|
|
be used by the translator. If no mapfile is provided by the user, the |
112 |
|
|
translator should have a standard mapping to assign material names |
113 |
|
|
based on some set of default paramters. (For example, arch2rad uses |
114 |
|
|
color alone to assign materials "c0" through "c255".) To accompany the |
115 |
|
|
default mapping, there should be a default materials file with |
116 |
|
|
corresponding definitions. These files should be placed in the |
117 |
|
|
Radiance library directory under "lib" (ie. "/usr/local/lib/ray/lib"). |
118 |
|
|
|
119 |
|
|
To just look at an Architrion building, a user might issue the following |
120 |
|
|
commands: |
121 |
|
|
|
122 |
|
|
oconv '\!gensky 6 15 12' /usr/local/lib/ray/lib/arch.mat \ |
123 |
|
|
'\!arch2rad model.txt' > model.oct |
124 |
greg |
1.2 |
rvu -av 3 3 3 -vp -20 -20 5 -vd 1 1 0 model.oct |
125 |
greg |
1.1 |
|
126 |
|
|
Note that by giving oconv commands instead of input files, no temporary |
127 |
|
|
files (other than the octree) are necessary. In a more complete |
128 |
|
|
example, the user might first create a qualifier list, then run the |
129 |
|
|
HyperCard stack for assigning materials, then convert the model |
130 |
|
|
with his own materials file, thus: |
131 |
|
|
|
132 |
|
|
arch2rad -n model.txt > model.qual |
133 |
|
|
HyperCard MatPick.stack # creates model.map from model.qual |
134 |
|
|
arch2rad -m model.map model.txt > model.rad |
135 |
|
|
oconv source.rad materials.rad model.rad > model.oct |
136 |
greg |
1.2 |
rvu -vf model.vp model.oct |
137 |
greg |
1.1 |
|
138 |
|
|
To write a new translator, include the "trans.h" file in ray/src/cv and |
139 |
|
|
link with trans.o and the standard Radiance library. You will need to |
140 |
|
|
define your own list of valid qualifiers and use the following routines |
141 |
|
|
from trans.c: |
142 |
|
|
|
143 |
|
|
fgetid(ID *idp; char *dls; FILE *fp) |
144 |
|
|
/* |
145 |
|
|
* Read an id (either a string or an integer) from fp |
146 |
|
|
* up to a character in dls. The delimiter will be discarded. |
147 |
|
|
* Return EOF at end of file, 0 otherwise. You should free |
148 |
|
|
* the id with the macro doneid(idp). |
149 |
|
|
*/ |
150 |
|
|
|
151 |
|
|
int |
152 |
|
|
findid(IDLIST *ilp; ID *idp; int insert) |
153 |
|
|
/* |
154 |
|
|
* Find (or insert) idp in the list ilp. Uses binary search |
155 |
|
|
* to find (or if insert is true, insert) an id in a sorted id |
156 |
|
|
* list. Returns index into ilp->id, or -1 if not found and no |
157 |
|
|
* insert. |
158 |
|
|
*/ |
159 |
|
|
|
160 |
|
|
int |
161 |
|
|
idcmp(ID *id1, *id2) |
162 |
|
|
/* |
163 |
|
|
* Compares two identifiers. Numbers compare less than strings. |
164 |
|
|
*/ |
165 |
|
|
|
166 |
|
|
write_quals(QLIST *qlp; IDLIST idl[]; FILE *fp) |
167 |
|
|
/* |
168 |
|
|
* Write out qualifiers in array of id lists idl[] to fp. |
169 |
|
|
* The qualifier list qlp is used to determine how many and |
170 |
|
|
* what to call the qualifiers. |
171 |
|
|
*/ |
172 |
|
|
|
173 |
|
|
RULEHD * |
174 |
|
|
getmapping(char *file; QLIST *qlp) |
175 |
|
|
/* |
176 |
|
|
* Read mapping rules from "file" and create a list of rules |
177 |
|
|
* in reverse order. Prints various syntax errors using eputs() |
178 |
|
|
* and calls quit() if there's a serious problem with the input. |
179 |
|
|
*/ |
180 |
|
|
|
181 |
|
|
matchid(ID *idp; IDMATCH *idm) |
182 |
|
|
/* |
183 |
|
|
* Checks to see if idp matches the id or range in idm. |
184 |
|
|
*/ |
185 |
|
|
|
186 |
|
|
Good luck! I will be happy to answer questions ([email protected]). |