ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgfdoc.tr
Revision: 1.1
Committed: Fri May 12 14:26:12 1995 UTC (29 years ago) by greg
Content type: application/x-troff
Branch: MAIN
Log Message:
Initial revision

File Contents

# Content
1 .\" SCCSid "$SunId$ LBL"
2 .nr PS 11
3 .ps 11
4 .nr VS 12
5 .vs 12
6 .nr PD .5v
7 .ds LF MGF
8 .ds RF Version 1.0
9 .DA May 1995
10 .TL
11 The Materials and Geometry Format
12 .AU
13 Greg Ward
14 .br
15 Lawrence Berkeley Laboratory
16 .NH
17 Introduction
18 .LP
19 The Materials and Geometry Format (referred to henceforth as MGF)
20 is a description language for 3-dimensional environments expressly
21 suited to visible light simulation and rendering.
22 The materials are physically-based and rely on standard and
23 well-accepted definitions of color, reflectance and transmittance
24 for good accuracy and reproducibility.
25 The geometry is based on boundary representation using simple
26 geometric primitives such as polygons, spheres and cones.
27 The file format itself is terse but human-readable ASCII text.
28 .NH 2
29 What makes MGF special?
30 .LP
31 There are three principal reasons to use MGF as an input language for
32 lighting simulation and physically-based rendering:
33 .RS
34 .IP 1.
35 It's the only existing format that describes materials physically.
36 .IP 2.
37 It is endorsed by the Illuminating Engineering Society of North
38 America (IESNA) as part of their LM-63-1995 standard for luminaire data.
39 .IP 3.
40 It's easy and fun to support since it comes with a standard parser
41 and sample scenes and objects at the web site,
42 "http://radsite.lbl.gov/mgf/HOME.html".
43 .RE
44 .LP
45 The standard parser provides both immediate and a long-term
46 benefits, since it presents a programming interface that is more
47 stable even than the language itself.
48 Unlike AutoCAD DXF and other de facto standards, a change to the
49 language will not break existing programs.
50 This is because the parser gives the calling software only those
51 entities it can handle.
52 If the translator understands only polygons, it will be given only
53 polygons.
54 If a new geometric primitive is included in a later version of the
55 standard, the new parser that comes with it will still be able to
56 express this entity as polygons.
57 Thus, the urgency of modifying code to support a changing standard
58 is removed, and long-term stability is assured.
59 .LP
60 This notion of
61 .I extensibility
62 is a cornerstone of the format, and it goes well beyond the
63 extensibility of other languages because is guarantees that new
64 versions of the standard will not break existing programs, and the
65 new information will be used as much as possible.
66 Other languages either require that all translators stay up to date
67 with the latest standard, or allow forward compatibility by simply
68 .I ignoring
69 new entities.
70 In MGF, if NURBS are added at some point and the translator or
71 loader does not handle them directly, the new version of the parser
72 will automatically convert them to smoothed polygons without
73 changing a single line of the calling program.
74 It is merely necessary to link to the new library, and all the new
75 entities are supported\(dg.
76 .FS
77 \(dgIf an old version of the parser encounters new entities it does
78 not recognize, the default action is to ignore them, printing a warning
79 message.
80 This may be overridden to support custom entities, but such
81 practice is discouraged because it weakens the standard.
82 .FE
83 .NH 2
84 What does MGF look like?
85 .LP
86 MGF has a simple entity-per-line structure, with a similar
87 appearance to Wavefront's .OBJ format.
88 Each entity is specified by a short keyword, and
89 arguments are separated by white space (tabs and/or spaces).
90 A newline may be escaped with a backslash ('\\'), in which case it
91 counts as a space.
92 Lines and continued lines may have up to 4096 characters, including
93 newlines, tabs and spaces.
94 A comment is an ignored entity whose keyword is the pound sign ('#').
95 .LP
96 Here is an MGF file that describes a simple two-drawer file cabinet:
97 .DS
98 # Conversion from inches to meters
99 xf -s .0254
100 # Surface material
101 m burgundy_formica =
102 c
103 cxy .362 .283
104 rd .0402
105 c
106 rs .0284 .05
107 sides 1
108 # Cabinet vertices
109 v fc.xy =
110 p .05 0 0
111 v fc.xY =
112 p .05 18 0
113 v fc.XY =
114 p 35.95 18 0
115 v fc.Xy =
116 p 35.95 0 0
117 # Cabinet
118 prism fc.xy fc.xY fc.XY fc.Xy 24
119 # Drawer vertices
120 v fcd.Xz =
121 p 34 0 0
122 v fcd.XZ =
123 p 34 0 10
124 v fcd.xZ =
125 p 0 0 10
126 v fcd.xz =
127 p 0 0 0
128 # Two drawers
129 o drawer
130 xf -t 1 18.1 2 -a 2 -t 0 0 11
131 prism fcd.xz fcd.Xz fcd.XZ fcd.xZ .9
132 xf
133 o
134 # End of units conversion
135 xf
136 .DE
137 .NH 2
138 MGF's place in the world of standards
139 .LP
140 MGF was developed initially to support detailed geometric
141 description of light fixtures for the IESNA luminaire data standard,
142 publication LM-63\(dg.
143 .FS
144 \(dgTo obtain the latest version of this standard, write to:
145 Illuminating Engineering Society of North America,
146 345 East 47th St.,
147 New York, NY 10017.
148 .FE
149 Existing standards for geometric description were either too
150 cumbersome (e.g.
151 .I Radiance)
152 or did not include physical materials (e.g. IGES).
153 It was noted early on that a standard able to fully describe
154 luminaires would necessarily be
155 capable of describing other objects as well; indeed whole
156 environments could be defined this way.
157 Since the descriptions would be physical, they could serve as input
158 to both lighting simulation and rendering software.
159 A standard language for describing the appearance of physical
160 objects has been lacking for some time, and current efforts in this
161 direction (i.e. STEP) seem several years away from fruition.
162 (There are other languages for describing realistic scenes
163 that deserve mention here, such as VRML and the Manchester Scene
164 Description Language, but none give specific attention to physical
165 material properties and are thus unsuitable for lighting
166 simulation.)\0
167 .LP
168 In short, we saw this as an opportunity to offer the lighting and
169 rendering community a simple and easy-to-support standard for
170 describing environments in a physically valid way.
171 Our hope is that this will promote sharing color, material and object
172 libraries as well as complete scene descriptions.
173 Sharing libraries is of obvious benefit to users and software
174 developers alike.
175 Sharing scenes should also permit
176 comparisons between rendering systems and
177 intervalidation of lighting calculations.
178 As anyone who works in this field knows, modeling is the most
179 difficult step in creating any simulation or rendering, and there is
180 no excuse for this data being held prisoner by a proprietary data
181 format.
182 .NH
183 MGF Basics
184 .LP
185 The default coordinate system in MGF is right-handed with
186 distances given in meters, though this can be effectively changed
187 by specifying a global transformation.
188 The transformation context is affected by the
189 .UL xf
190 entity, and the whole of MGF can be understood in terms of entities
191 and contexts.
192 .NH 2
193 Entities and Contexts
194 .LP
195 An
196 .I entity
197 in MGF is any non-blank line, which must be one of a finite set of
198 command keywords followed by zero or more arguments.
199 (As mentioned previously, an entity may continue over multiple lines
200 by escaping the newline with a backslash.)\0
201 Table 1 gives a list of entities and their expected arguments.
202 Section 3 gives more detailed information on each entity.
203 .KF
204 .TS
205 expand, box;
206 l l l.
207 Keyword Arguments Interpretation
208 = = =
209 # [anything ...] a comment
210 o [name] begin/end object context
211 xf [xform] begin/end transformation context
212 i pathname [xform] include file (with transformation)
213 ies pathname [-m f][xform] include IES luminaire (with transformation)
214 _ _ _
215 c [id [= [template]]] get/set color context
216 cxy x y set CIE (x,y) chromaticity for current color
217 cspec l_min l_max v1 v2 ... set relative spectrum for current color
218 cct temperature set spectrum based on black body temperature
219 cmix w1 c1 w2 c2 ... mix named colors to make current color
220 _ _ _
221 m [id [= [template]]] get/set material context
222 sides {1|2} set number of sides for current material
223 rd rho_d set diffuse reflectance for current material
224 td tau_d set diffuse transmittance for current material
225 ed epsilon_d set diffuse emittance for current material
226 rs rho_s alpha_r set specular reflectance for current material
227 ts tau_s alpha_t set specular transmittance for current material
228 ir n_real n_imag set index of refraction for current material
229 _ _ _
230 v [id [= [template]]] get/set vertex context
231 p x y z set point position for current vertex
232 n dx dy dz set surface normal for current vertex
233 _ _ _
234 f v1 v2 v3 ... polygon using current material, spec. vertices
235 sph vc radius sphere
236 cyl v1 radius v2 truncated right cylinder (open-ended)
237 cone v1 rad1 v2 rad2 truncated right cone (open-ended)
238 prism v1 v2 v3 ... length truncated right prism (closed solid)
239 ring vc rmin rmax circular ring with inner and outer radii
240 torus vc rmin rmax circular torus with inner and outer radii
241 .TE
242 .QP
243 .B "Table 1".
244 MGF entities and their arguments.
245 Arguments in brackets are optional.
246 Arguments in curly braces mean one of the given choices must
247 appear.
248 Ellipsis (...) mean that any number of arguments may be given.
249 .sp
250 .KE
251 .LP
252 A
253 .I context
254 describes the current state of the interpreter, and affects or is
255 affected by certain entities as they are read in.
256 MGF contexts can be divided into two types,
257 .I "hierarchical contexts"
258 and
259 .I "named contexts".
260 .LP
261 Hierarchical contexts are manipulated by a single entity and
262 have an associated "stack" onto which new
263 contexts are "pushed" using the entity.
264 The last context may be "popped" by giving the entity again with no
265 arguments.
266 The two hierarchical contexts in MGF are the current transformation,
267 manipulated with the
268 .UL xf
269 entity, and the current object, manipulated with the
270 .UL o
271 entity.
272 .KF
273 .TS
274 expand, allbox;
275 l c l l l.
276 Context Cntl. Entity Default Value Field Entities Affects
277 = = = = =
278 Object o - - -
279 Transform xf - - T{
280 f, sph, cyl, cone,
281 ring, torus, prism
282 T}
283 Material m 2-sided black T{
284 sides, rd, td,
285 ed, rs, ts
286 T} T{
287 f, sph, cyl, cone,
288 ring, torus, prism
289 T}
290 Color c neutral grey T{
291 cxy, cspec, cct, cmix
292 T} T{
293 rd, td, ed, rs, ts
294 T}
295 Vertex v T{
296 (0,0,0),
297 no normal
298 T} p, n T{
299 f, sph, cyl, cone,
300 ring, torus, prism
301 T}
302 .TE
303 .QP
304 .B "Table 2".
305 MGF contexts and their related entities and default values.
306 .sp
307 .KE
308 .LP
309 Named contexts in contrast hold sets of values that are swapped
310 in and out one at a time.
311 There are three named contexts in MGF, the current material, the
312 current color and the current vertex.
313 Each one may be associated with an identifier (any non-white
314 sequence of printing ASCII characters beginning with a letter),
315 and one of each is in effect at any given time.
316 Initially, these contexts are unnamed, and invoking an unnamed
317 context always returns to the original (default) values.
318 (See Table 2 for a list of contexts, their related
319 entities and defaults.)\0
320 .LP
321 It is easiest to think of a context as a "scratch space" where
322 values are written by some entities and read by others.
323 Naming a context allows us to reestablish the same scratch space
324 later, usually for reference but it can be altered as well.
325 Let us say we wanted to create a smooth blue plastic material with a
326 diffuse reflectance of 20% and a specular reflectance of 4%:
327 .DS
328 # Establish a new material context called "blue_plastic"
329 m blue_plastic =
330 # Reestablish a previous color context called "blue"
331 c blue
332 # Set the diffuse reflectance, which uses the above color
333 rd .20
334 # Get the unnamed color context (always starts out grey)
335 c
336 # Set the specular reflectance, which is uncolored
337 rs .04 0
338 # We're done, the current material context is now "blue_plastic"
339 .DE
340 Note that the above assumes that we have previously defined a color
341 context named "blue".
342 If we forgot to do that, the above description would generate an
343 "undefined" error.
344 The color context affects the material context indirectly because it
345 is read by the specular and diffuse reflectance entities, which are
346 in turn written to the current material.
347 It is not necessary to indent the entities that affect the material
348 definition, but it improves readability.
349 Note also that there is no explicit end to the material definition.
350 As long as a context remains in effect, its contents may be altered
351 by its field entities.
352 This will not affect previous uses of the context, however.
353 For example, a surface entity following the above definition will
354 have the specified color and reflectance, and later changes to the
355 material "blue_plastic" will have no effect on it.
356 .LP
357 Each of the three named contexts has an associated entity that
358 controls it.
359 The material context is controlled by the
360 .UL m
361 entity, the color context is controlled by the
362 .UL c
363 entity, and the vertex context is controlled by the
364 .UL v
365 entity.
366 There are exactly four forms for each entity.
367 The first form is the keyword by itself, which establishes
368 an unnamed context with predetermined default values.
369 This is a useful way to set values without worrying about saving
370 them for recall later.
371 The second form is to give the keyword with a previously defined
372 name.
373 This reestablishes a prior context for reuse.
374 The third form is to give the keyword with a name followed by an
375 equals sign.
376 (There must be a space between the name and the equals sign, since
377 it is a separate argument.)\0
378 This establishes a new context and assigns it the same default
379 values as the unnamed context.
380 The fourth and final form gives the keyword followed by a name then
381 an equals then the name of a previous context definition.
382 This establishes a new context for the first name, assigning the
383 values from the second named context rather than the usual defaults.
384 This is a convenient way create an alias or
385 to modify a context under a new name (i.e. "save as").
386 .NH 2
387 Hierarchical Contexts and Transformations
388 .LP
389 As mentioned in the last subsection, there are two hierarchical
390 contexts in MGF, the current object and the current transformation.
391 We will start by discussing the current object, since it is
392 the simpler of the two.
393 .NH 3
394 Objects
395 .LP
396 There is no particular need in lighting simulation or rendering to
397 name objects, but it may help the user
398 to know what object a particular surface is associated with.
399 The
400 .UL o
401 entity provides a convenient mechanism for associating names with
402 surfaces.
403 The basic use of this entity is as follows:
404 .DS
405 o object_name
406 [object entities...]
407 o subobject_name
408 [subobject entities...]
409 o
410 [more object entities and subobjects...]
411 o
412 .DE
413 The
414 .UL o
415 keyword by itself marks the end of an object context.
416 Any number of hierarchical context levels are supported, and there are no
417 rules governing the choice of object names except that they begin
418 with a letter and be made up of printing, non-white ASCII characters.
419 Indentation is not necessary of course, but it does improve
420 readability.
421 .NH 3
422 Transformations
423 .LP
424 MGF supports only rigid-body (i.e. non-distorting) transformations
425 with uniform scaling.
426 Unlike the other contexts, transformations have no associated
427 name, only arguments.
428 Thus, there is no way to reestablish a previous transformation other
429 than to give the same arguments over again.
430 Since the arguments are concise and self-explanatory, this was thought
431 sufficient.
432 The following transformation flags and
433 parameters are defined:
434 .TS I
435 l l.
436 -t dx dy dz translate objects along the given vector
437 -rx degrees rotate objects about the X-axis
438 -ry degrees rotate objects about the Y-axis
439 -rz degrees rotate objects about the Z-axis
440 -s scalefactor scale objects by the given factor
441 -mx mirror objects about the Y-Z plane
442 -my mirror objects about the X-Z plane
443 -mz mirror objects about the X-Y plane
444 -i N repeat the following arguments N times
445 -a N make an array of N geometric instances
446 .TE
447 Transform arguments have a cumulative effect.
448 That is, a rotation
449 about X of 20 degrees followed by a rotation about X of -50 degrees
450 results in a total rotation of -30 degrees.
451 However, if the two
452 rotations are separated by some translation vector, the cumulative
453 effect is quite different.
454 It is best to think of each argument as
455 acting on the included geometric objects, and each subsequent transformation
456 argument affects the objects relative to their new position/orientation.
457 .LP
458 For example, rotating an object about its center is most easily done
459 by translating
460 the object back to the origin, applying the desired rotation, and translating
461 it again back to its original position, like so:
462 .DS
463 # rotate an included object 20 degrees clockwise looking down
464 # an axis parallel to Y and passing through the point (15,0,-35)
465 xf -t -15 0 35 -ry -20 -t 15 0 -35
466 i object.mgf
467 xf
468 .DE
469 Note that the include entity,
470 .UL i,
471 permits a transformation to be given with it, so the above could
472 have been written more compactly as:
473 .DS
474 i object.mgf -t -15 0 35 -ry -20 -t 15 0 -35
475 .DE
476 .LP
477 Rotations are given in degrees counter-clockwise about a principal axis.
478 That is, with the thumb of the right hand pointing in the direction
479 of the axis, rotation follows the curl of the fingers.
480 .LP
481 The transform entity itself is cumulative, but in the reverse
482 order to its arguments.
483 That is, later transformations (i.e. enclosed transformations)
484 are prepended to existing (i.e. enclosing) ones.
485 A transform command
486 with no arguments is used to return to the previous condition.
487 It is
488 necessary that transforms and their end statements ("xf" by itself) be
489 balanced in a file, so that later or enclosing files are not affected.
490 .LP
491 Transformations apply only to geometric types, e.g. polygons, spheres, etc.
492 Vertices and the components that go into geometry are not directly affected.
493 This is to avoid confusion and the inadvertent multiple application of a
494 given transformation.
495 For example:
496 .DS
497 xf -t 5 0 0
498 v v1 =
499 p 0 10 0
500 n 0 0 1
501 xf -rx 180
502 # Transform now in effect is "-rx 180 -t 5 0 0"
503 ring v1 0 2
504 xf
505 xf
506 .DE
507 The final ring center is (5,-10,0) -- note that the vertex itself is
508 not affected by the transformation, only the geometry that calls on
509 it.
510 The normal orientation is (0,0,-1) due to the rotation about X,
511 which also reversed the sign of the central Y coordinate.
512 .NH 3
513 Arrays
514 .LP
515 The -a N transform specification causes the following transform
516 arguments to be repeated along with the contents of the included
517 objects N times.
518 The first instance of the geometry will be in its
519 initial location; the second instance will be repositioned according
520 to the named transformation; the third instance will be repositioned by
521 applying this transformation twice, and so on up to N-1 applications.
522 .LP
523 Multi-dimensional arrays may be specified with a single include
524 entity by giving multiple array commands separated by their
525 corresponding transforms.
526 A final transformation may be given
527 by preceding it with a -i 1 specification.
528 In other words, the
529 scope of an array command continues until the next -i or -a option.
530 .LP
531 The following MGF description places 60 spheres at a one unit spacing
532 in a 3x4x5 array, then moves the whole thing to an origin of
533 (15,30,45):
534 .DS
535 v v0 =
536 p 0 0 0
537 xf -a 3 -t 1 0 0 -a 4 -t 0 1 0 -a 5 -t 0 0 1 -i 1 -t 15 30 45
538 sph v0 0.1
539 xf
540 .DE
541 Note the "-i 1" in the specification, which marks the end of the
542 third array arguments before the final translation.
543 .NH 2
544 Detailed MGF Example
545 .LP
546 The following example of a simple room with a single door
547 and six file cabinets shows MGF in action, with copious comments to
548 help explain what's going on.
549 .DS
550 # "ceiling_tile" is a diffuse white surface with 75% reflectance:
551 # Create new named material context and clear it
552 m ceiling_tile =
553 # Specify one-sided material so we can see through from above
554 sides 1
555 # Set neutral color
556 c
557 # Set diffuse reflectance
558 rd .75
559 # "stainless_steel" is a mostly specular surface with 70% reflectance:
560 m stainless_steel =
561 sides 1
562 c
563 # Set specular reflectance to 50%, .08 roughness
564 rs .5 .08
565 # Other 20% reflectance is diffuse
566 rd .2
567
568 # The following materials were measured with a spectrophotometer:
569 m beige_paint =
570 sides 1
571 # Set diffuse spectral reflectance
572 c
573 # Spectrum measured in 10 nm increments from 400 to 700 nm
574 cspec 400 700 35.29 44.87 47.25 47.03 46.87 47.00 47.09 \\\\
575 47.15 46.80 46.17 46.26 48.74 51.08 51.31 51.10 \\\\
576 51.11 50.52 50.36 51.72 53.61 53.95 52.08 49.49 \\\\
577 48.30 48.75 49.99 51.35 52.75 54.44 56.34 58.00
578 rd 0.5078
579 # Neutral (grey) specular component
580 c
581 rs 0.0099 0.08000
582 m mottled_carpet =
583 sides 1
584 c
585 cspec 400 700 11.23 11.28 11.39 11.49 11.61 11.73 11.88 \\\\
586 12.02 12.12 12.19 12.30 12.37 12.37 12.36 12.34 \\\\
587 12.28 12.22 12.29 12.45 12.59 12.70 12.77 12.82 \\\\
588 12.88 12.98 13.24 13.67 14.31 15.55 17.46 19.75
589 rd 0.1245
590 m reddish_cloth =
591 # 2-sided so we can observe it from behind
592 sides 2
593 c
594 cspec 400 700 28.62 27.96 27.86 28.28 29.28 30.49 31.61 \\\\
595 32.27 32.26 31.83 31.13 30.07 29.14 29.03 29.69 \\\\
596 30.79 32.30 33.90 34.56 34.32 33.85 33.51 33.30 \\\\
597 33.43 34.06 35.26 37.04 39.41 42.55 46.46 51.00
598 rd 0.3210
599 m burgundy_formica =
600 sides 1
601 c
602 cspec 400 700 3.86 3.74 3.63 3.51 3.34 3.21 3.14 \\\\
603 3.09 3.08 3.14 3.13 2.91 2.72 2.74 2.72 \\\\
604 2.60 2.68 3.40 4.76 6.05 6.65 6.75 6.68 \\\\
605 6.63 6.56 6.51 6.46 6.41 6.36 6.34 6.34
606 rd 0.0402
607 c
608 rs 0.0284 0.05000
609 m speckled_grey_formica =
610 sides 1
611 c
612 cspec 400 700 30.95 44.77 51.15 52.60 53.00 53.37 53.68 \\\\
613 54.07 54.33 54.57 54.85 55.20 55.42 55.51 55.54 \\\\
614 55.46 55.33 55.30 55.52 55.81 55.91 55.92 56.00 \\\\
615 56.22 56.45 56.66 56.72 56.58 56.44 56.39 56.39
616 rd 0.5550
617 c
618 rs 0.0149 0.15000
619
620 # 40' x 22' x 9' office space with no windows and one door
621
622 # All measurements are in inches, so enclose with a metric conversion:
623 xf -s .0254
624
625 # The room corner vertices:
626 v rc.xyz =
627 p 0 0 0
628 v rc.Xyz =
629 p 480 0 0
630 v rc.xYz =
631 p 0 264 0
632 v rc.xyZ =
633 p 0 0 108
634 v rc.XYz =
635 p 480 264 0
636 v rc.xYZ =
637 p 0 264 108
638 v rc.XyZ =
639 p 480 0 108
640 v rc.XYZ =
641 p 480 264 108
642
643 # The floor:
644 # Push object name
645 o floor
646 # Get previously defined carpet material
647 m mottled_carpet
648 # Polygonal face using defined vertices
649 f rc.xyz rc.Xyz rc.XYz rc.xYz
650 # Pop object name
651 o
652
653 # The ceiling:
654 o ceiling
655 m ceiling_tile
656 f rc.xyZ rc.xYZ rc.XYZ rc.XyZ
657 o
658
659 # The door outline vertices:
660 v do.xz =
661 p 216 0 0
662 v do.Xz =
663 p 264 0 0
664 v do.xZ =
665 p 216 0 84
666 v do.XZ =
667 p 264 0 84
668
669 # The walls:
670 o wall
671 m beige_paint
672 o x
673 f rc.xyz rc.xYz rc.xYZ rc.xyZ
674 o
675 o X
676 f rc.Xyz rc.XyZ rc.XYZ rc.XYz
677 o
678 o y
679 f rc.xyz rc.xyZ rc.XyZ rc.Xyz do.Xz do.XZ do.xZ do.xz
680 o
681 o Y
682 f rc.xYz rc.XYz rc.XYZ rc.xYZ
683 o
684 o
685
686 # The door and jam vertices:
687 v djo.xz =
688 p 216 .5 0
689 v djo.xZ =
690 p 216 .5 84
691 v djo.XZ =
692 p 264 .5 84
693 v djo.Xz =
694 p 264 .5 0
695 v dji.Xz =
696 p 262 .5 0
697 v dji.XZ =
698 p 262 .5 82
699 v dji.xZ =
700 p 218 .5 82
701 v dji.xz =
702 p 218 .5 0
703 v door.xz =
704 p 218 0 0
705 v door.xZ =
706 p 218 0 82
707 v door.XZ =
708 p 262 0 82
709 v door.Xz =
710 p 262 0 0
711
712 # The door, jam and knob
713 o door
714 m burgundy_formica
715 f door.xz door.xZ door.XZ door.Xz
716 o jam
717 m beige_paint
718 f djo.xz djo.xZ djo.XZ djo.Xz dji.Xz dji.XZ dji.xZ dji.xz
719 f djo.xz do.xz do.xZ djo.xZ
720 f djo.xZ do.xZ do.XZ djo.XZ
721 f djo.Xz djo.XZ do.XZ do.Xz
722 f dji.xz dji.xZ door.xZ door.xz
723 f dji.xZ dji.XZ door.XZ door.xZ
724 f dji.Xz door.Xz door.XZ dji.XZ
725 o
726 o knob
727 m stainless_steel
728 # Define vertices needed for curved geometry
729 v kb1 =
730 p 257 0 36
731 v kb2 =
732 p 257 .25 36
733 n 0 1 0
734 v kb3 =
735 p 257 2 36
736 # 1" diameter cylindrical base from kb1 to kb2
737 cyl kb1 1 kb2
738 # Ring at base of knob stem
739 ring kb2 .4 1
740 # Knob stem
741 cyl kb2 .4 kb3
742 # Spherical knob
743 sph kb3 .85
744 o
745 o
746
747 i cubfurn.inc -mx -t 405 133.5 0
748 o
749
750 # Six file cabinets (36" wide each)
751 # ("filecab.inc" was given as an earlier example in Section 1.2)
752 o filecab.x
753 # include a file as an array of three 36" apart
754 i filecab.inc -t -36 0 0 -rz -90 -t 1 54 0 -a 3 -t 0 36 0
755 o
756 o filecab.X
757 # the other three cabinets
758 i filecab.inc -rz 90 -t 479 54 0 -a 3 -t 0 36 0
759 o
760
761 # End of transform from inches to meters:
762 xf
763
764 # The 10 recessed fluorescent ceiling fixtures
765 ies hlrs2gna.ies -t 1.2192 2.1336 2.74 -a 5 -t 2.4384 0 0 -a 2 -t 0 2.4384 0
766 .DE
767 .bp
768 .NH
769 MGF Entity Reference
770 .LP
771 There are currently 28 entities in the MGF specification.
772 For ease of reference we have broken these into five categories:
773 .IP 1.
774 General
775 .TS I
776 lw(.75i) lw(1.75i) lw(3i).
777 # [anything ...] a comment
778 o [name] begin/end object context
779 xf [xform] begin/end transformation context
780 i pathname [xform] include file (with transformation)
781 ies pathname [-m f][xform] include IES luminaire (with transformation)
782 .TE
783 .IP 2.
784 Color
785 .TS I
786 lw(.75i) lw(1.75i) lw(3i).
787 c [id [= [template]]] get/set color context
788 cxy x y set CIE (x,y) chromaticity for current color
789 cspec l_min l_max v1 v2 ... set relative spectrum for current color
790 cct temperature set spectrum based on black body temperature
791 cmix w1 c1 w2 c2 ... mix named colors to make current color
792 .TE
793 .IP 3.
794 Material
795 .TS
796 lw(.75i) lw(1.75i) lw(3i).
797 m [id [= [template]]] get/set material context
798 sides {1|2} set number of sides for current material
799 rd rho_d set diffuse reflectance for current material
800 td tau_d set diffuse transmittance for current material
801 ed epsilon_d set diffuse emittance for current material
802 rs rho_s alpha_r set specular reflectance for current material
803 ts tau_s alpha_t set specular transmittance for current material
804 ir n_real n_imag set index of refraction for current material
805 .TE
806 .IP 4.
807 Vertex
808 .TS
809 lw(.75i) lw(1.75i) lw(3i).
810 v [id [= [template]]] get/set vertex context
811 p x y z set point position for current vertex
812 n dx dy dz set surface normal for current vertex
813 .TE
814 .IP 5.
815 Geometry
816 .TS
817 lw(.75i) lw(1.75i) lw(3i).
818 f v1 v2 v3 ... polygon using current material, spec. vertices
819 sph vc radius sphere
820 cyl v1 radius v2 truncated right cylinder (open-ended)
821 cone v1 rad1 v2 rad2 truncated right cone (open-ended)
822 prism v1 v2 v3 ... length truncated right prism (closed solid)
823 ring vc rmin rmax circular ring with inner and outer radii
824 torus vc rmin rmax circular torus with inner and outer radii
825 .TE
826 .ds LH General Entities
827 .ds RH #
828 .bp
829 .SH
830 NAME
831 .LP
832 # - a comment
833 .SH
834 SYNOPSIS
835 .LP
836 .B #
837 [
838 .I anything
839 ]
840 .SH
841 DESCRIPTION
842 .LP
843 A comment is a bit of text explanation.
844 Since it is an entity like any other (except that it has no effect),
845 there must be at least one space between the keyword (which is a
846 pound sign) and the "arguments," and the end of line may be escaped
847 as usual with the backslash character ('\\').
848 .LP
849 A comment may actually be used to hold auxiliary information such as
850 view parameters, which may be interpreted by some destination program.
851 Care should be taken under such circumstances that the user does not
852 inadvertently mung or mimic this information in other comments, and
853 it is therefore advisable to use an additional set of identifying
854 characters to distinguish such data.
855 .SH
856 EXAMPLE
857 .DS
858 # The following include file is in inches, so convert to meters
859 i cubgeom.inc -s .0254
860 # Stuff we don't want to see at the moment:
861 # i person.mgf -t 3 2 0
862 # ies hlrs3gna.ies -rz 90 -t 1.524 1.8288 2.74 \\\\
863 -a 6 -t 1.8288 0 0 -a 2 -t 0 3.048 0
864 .DE
865 .ds RH O
866 .bp
867 .SH
868 NAME
869 .LP
870 o - begin or end object context
871 .SH
872 SYNOPSIS
873 .LP
874 .B o
875 [
876 .I name
877 ]
878 .SH
879 DESCRIPTION
880 .LP
881 If
882 .I name
883 is given, we push a new object context onto the stack, which is to
884 say that we begin a new subobject by this name\(dg.
885 .FS
886 \(dgA name is any sequence of printing, non-white ASCII characters
887 beginning with a letter.
888 .FE
889 If the
890 .UL o
891 keyword is given by itself, then we pop the last object context off
892 the stack, which means that we leave the current subobject.
893 .LP
894 All geometry between the start of an object context and its matching
895 end statement is associated with the given name.
896 This may be used in modeling software to help identify objects and
897 subobjects, or it may be ignored altogether.
898 .LP
899 Object begin and end statements should be balanced in a file, and
900 care should be taken not to overlap transform
901 .UL (xf)
902 contexts with object contexts, especially when arrays are involved.
903 This is because the standard parser will assign object contexts to
904 instanced geometry, which can get confused with other object
905 contexts if a clear enclosure is not maintained.
906 .SH
907 EXAMPLE
908 .DS
909 o body
910 o torso
911 i torso.mgf
912 o
913 o arm
914 o left
915 i leftarm.mgf
916 o
917 o right
918 i leftarm.mgf -mx
919 o
920 o
921 o
922 .DE
923 .SH
924 SEE ALSO
925 .LP
926 .UL xf
927 .ds RH XF
928 .bp
929 .SH
930 NAME
931 .LP
932 xf - begin or end transformation context
933 .SH
934 SYNOPSIS
935 .LP
936 .B xf
937 [
938 .I transform
939 ]
940 .SH
941 DESCRIPTION
942 .LP
943 If a set of
944 .I transform
945 arguments are given, we push a new transformation context onto the
946 stack.
947 If the
948 .UL xf
949 keyword is given by itself, then we pop the last transformation
950 context off the stack.
951 The total transformation in effect at any given time is
952 computed by prepending each set subcontext arguments onto those of
953 its enclosing context.
954 This and other details about transformation specifications
955 are explained in some detail in section 2.2.2.
956 .LP
957 The following transformation flags and
958 parameters are defined:
959 .TS
960 center;
961 l l.
962 -t dx dy dz translate objects along the given vector
963 -rx degrees rotate objects about the X-axis
964 -ry degrees rotate objects about the Y-axis
965 -rz degrees rotate objects about the Z-axis
966 -s scalefactor scale objects by the given factor
967 -mx mirror objects about the Y-Z plane
968 -my mirror objects about the X-Z plane
969 -mz mirror objects about the X-Y plane
970 -i N repeat the following arguments N times
971 -a N make an array of N geometric instances
972 .TE
973 .SH
974 EXAMPLE
975 .DS
976 # Create 3x5 array of evenly-spaced spheres (grid size = 3)
977 v vc =
978 p 0 0 0
979 xf -t 1 1 10 -a 3 -t 3 0 0 -a 5 -t 0 3 0
980 sph vc .5
981 xf
982 .DE
983 .SH
984 SEE ALSO
985 .LP
986 .UL i,
987 .UL ies,
988 .UL o
989 .ds RH I
990 .bp
991 .SH
992 NAME
993 .LP
994 i - include MGF data file
995 .SH
996 SYNOPSIS
997 .LP
998 .B i
999 .I pathname
1000 [
1001 .I transform
1002 ]
1003 .SH
1004 DESCRIPTION
1005 .LP
1006 Include the information contained in the file
1007 .I pathname.
1008 If a
1009 .I transform
1010 specification is given, then it will be applied as though the
1011 include statement were enclosed by beginning and ending
1012 .UL xf
1013 entities with this transformation.
1014 .LP
1015 The
1016 .I pathname
1017 will be interpreted relative to the enclosing MGF file.
1018 That is, if the file containing the include statement is in some
1019 parent or subdirectory, then the given pathname is appended to this
1020 directory.
1021 It is illegal to specify a
1022 .I pathname
1023 relative to the root directory, and the MGF standard requires that
1024 all filenames adhere to the ISO-9660 8.3 name format for maximum
1025 portability between systems.
1026 The directory separator is defined to be slash ('/'), and drive
1027 specifications (such as "c:") are not allowed.
1028 All pathnames should be given in lower case, and will be converted to
1029 upper case on systems that require it.
1030 (That way, there are no accidental name collisions.)\0
1031 .LP
1032 The suggested suffix for MGF-adherent files is ".mgf".
1033 Files that are not in metric units but are in MGF may be given any
1034 suffix, but we suggest using ".inc" as a convention.
1035 .SH
1036 EXAMPLE
1037 .DS
1038 # Define vertices for 62x30" partition
1039 i pv62x30.inc
1040 # Insert 2 62x30" partitions
1041 o cpart1
1042 i partn.inc -t 75 130.5 0
1043 o
1044 o cpart3
1045 i partn.inc -t 186 130.5 0
1046 o
1047 # Define vertices for 62x36" partition
1048 i pv62x36.inc
1049 # Insert 62x36" partition
1050 o cpart2
1051 i partn.inc -t 105 130.5 0
1052 o
1053 .DE
1054 .SH
1055 SEE ALSO
1056 .LP
1057 .UL ies,
1058 .UL o,
1059 .UL xf
1060 .ds RH IES
1061 .bp
1062 .SH
1063 NAME
1064 .LP
1065 ies - include IESNA luminaire file
1066 .SH
1067 SYNOPSIS
1068 .LP
1069 .B ies
1070 .I pathname
1071 [
1072 .B \-m
1073 .I multiplier
1074 ]
1075 [
1076 .I transform
1077 ]
1078 .SH
1079 DESCRIPTION
1080 .LP
1081 Load the IES standard luminaire information contained in the file
1082 .I pathname.
1083 If a
1084 .I multiplier
1085 is given, all candela values will be multiplied by this factor.
1086 (This option must appear first if present.)\0
1087 If a
1088 .I transform
1089 specification is given, then it will be applied as though the
1090 statement were enclosed by beginning and ending
1091 .UL xf
1092 entities with this transformation.
1093 .LP
1094 The
1095 .I pathname
1096 will be interpreted relative to the enclosing MGF file, and all
1097 restrictions discussed under the
1098 .UL i
1099 entity also apply to the IES file name.
1100 The suggested suffix is ".ies", but this has not been followed
1101 consistently by lighting manufacturers.
1102 .SH
1103 EXAMPLE
1104 .DS
1105 # Insert 10 2x4' fluorescent troffers in two groups
1106 ies cf9pr240.ies -t 3.6576 2.1336 2.74 -a 3 -t 2.4384 0 0 -a 2 -t 0 2.4384 0
1107 ies cf9pr240.ies -rz 90 -t 1.2192 1.8288 2.74 \\\\
1108 -a 2 -t 9.7536 0 0 -a 2 -t 0 3.048 0
1109 .DE
1110 .SH
1111 SEE ALSO
1112 .LP
1113 .UL i,
1114 .UL o,
1115 .UL xf
1116 .ds LH Color Entities
1117 .ds RH C
1118 .bp
1119 .SH
1120 NAME
1121 .LP
1122 c - get or set the current color context
1123 .SH
1124 SYNOPSIS
1125 .LP
1126 .B c
1127 [
1128 .I id
1129 [
1130 .B =
1131 [
1132 .I template
1133 ]
1134 ]
1135 ]
1136 .SH
1137 DESCRIPTION
1138 .LP
1139 If the
1140 .UL c
1141 keyword is given by itself, then it establishes the unnamed color
1142 context, which is neutral (i.e. equal-energy) grey.
1143 This context may be modified, but the changes will not be saved.
1144 .LP
1145 If the keyword is followed by an identifier
1146 .I id,
1147 then it reestablishes a previous context.
1148 If the specified context was never defined, an error will result.
1149 .LP
1150 If the entity is given with an identifier
1151 followed by an equals sign ('='), then a new context is established,
1152 and cleared to the default neutral grey.
1153 (Note that the equals sign must be separated from other
1154 arguments by white space to be properly recognized.)\0
1155 If the equals sign is followed by a second identifier
1156 .I template,
1157 then this previously defined color will be used as a source of
1158 default values rather than grey.
1159 This is most useful for establishing a color alias.
1160 .SH
1161 EXAMPLE
1162 .DS
1163 # Define the color "red32"
1164 c red32 =
1165 cxy .42 .15
1166 # Make "cabinet_color" an alias for "red32"
1167 c cabinet_color = red32
1168
1169 # Later in another part of the description...
1170
1171 # Get our cabinet color
1172 c cabinet_color
1173 # Get the geometry
1174 i cabgeom.mgf
1175 .DE
1176 .SH
1177 SEE ALSO
1178 .LP
1179 .UL cct,
1180 .UL cmix,
1181 .UL cspec,
1182 .UL cxy,
1183 .UL m
1184 .ds RH CXY
1185 .bp
1186 .SH
1187 NAME
1188 .LP
1189 cxy - set the CIE (x,y) chromaticity for the current color
1190 .SH
1191 SYNOPSIS
1192 .LP
1193 .B cxy
1194 .I "x y"
1195 .SH
1196 DESCRIPTION
1197 .LP
1198 This entity sets the current color using (x,y) chromaticity
1199 coordinates for the 1931 CIE standard 2 degree observer.
1200 Legal values for
1201 .I x
1202 and
1203 .I y
1204 are greater than zero and sum to less than one, and more
1205 specifically they must fit within the curve of the visible spectrum.
1206 The
1207 .I x
1208 coordinate roughly corresponds to the red part of the spectrum and
1209 the
1210 .I y
1211 coordinate corresponds to the green.
1212 The CIE z coordinate is implicit, since it is equal to (1-x-y).
1213 .LP
1214 All colors in MGF are absolute, thus colorimeter measurements should
1215 be conducted the same for surfaces as for light sources.
1216 Applying a standard illuminant calculation is redundant and
1217 introduces inaccuracies, and should therefore be avoided if
1218 possible.
1219 .LP
1220 Conversion between CIE colors and those more commonly used in
1221 computer graphics are described in the application notes section
1222 6.1.1.
1223 .SH
1224 EXAMPLE
1225 .DS
1226 # Set unnamed color context
1227 c
1228 # Set CIE chromaticity to a bluish hue
1229 cxy .15 .2
1230 # Apply color to diffuse reflectance of 15%
1231 rd .15
1232 .DE
1233 .SH
1234 SEE ALSO
1235 .LP
1236 .UL c,
1237 .UL cct,
1238 .UL cmix,
1239 .UL cspec
1240 .ds RH CSPEC
1241 .bp
1242 .SH
1243 NAME
1244 .LP
1245 cspec - set the relative spectrum for the current color
1246 .SH
1247 SYNOPSIS
1248 .LP
1249 .B cspec
1250 .I "l_min l_max o1 o2 ... oN"
1251 .SH
1252 DESCRIPTION
1253 .LP
1254 Assign a relative spectrum measured between
1255 .I l_min
1256 and
1257 .I l_max
1258 nanometers at evenly spaced intervals.
1259 The first value,
1260 .I o1
1261 corresponds to the measurement at
1262 .I l_min,
1263 and the last value,
1264 .I oN
1265 corresponds to the measurement at
1266 .I l_max.
1267 Values in between are separated by
1268 .I "(l_max-l_min)/(N-1)"
1269 nanometers.
1270 All values must be non-negative, and the spectrum outside of the
1271 specified range is assumed to be zero.
1272 (The visible range is 380 to 780 nm.)\0
1273 The actual units and scale of the measurements do not matter,
1274 since the total will be
1275 normalized according to whatever the color is modifying
1276 (e.g. photometric reflectance or emittance).
1277 .SH
1278 EXAMPLE
1279 .DS
1280 # Color measured at 10 nm increments from 400 to 700
1281 m reddish_cloth =
1282 c
1283 cspec 400 700 28.62 27.96 27.86 28.28 29.28 30.49 31.61 \\\\
1284 32.27 32.26 31.83 31.13 30.07 29.14 29.03 29.69 \\\\
1285 30.79 32.30 33.90 34.56 34.32 33.85 33.51 33.30 \\\\
1286 33.43 34.06 35.26 37.04 39.41 42.55 46.46 51.00
1287 rd 0.3210
1288 .DE
1289 .SH
1290 SEE ALSO
1291 .LP
1292 .UL c,
1293 .UL cct,
1294 .UL cmix,
1295 .UL cxy
1296 .ds RH CCT
1297 .bp
1298 .SH
1299 NAME
1300 .LP
1301 cct - set the current color to a black body spectrum
1302 .SH
1303 SYNOPSIS
1304 .LP
1305 .B cct
1306 .I temperature
1307 .SH
1308 DESCRIPTION
1309 .LP
1310 The
1311 .UL cct
1312 entity sets the current color to the spectrum of an ideal
1313 black body radiating at
1314 .I temperature
1315 degrees Kelvin.
1316 This is often the most convenient way to set the color of an
1317 incandescent light source, but it is not recommended for
1318 fluorescent lamps or other materials that do not fit a
1319 black body spectrum.
1320 .SH
1321 EXAMPLE
1322 .DS
1323 # Define an incandescent source material at 3000 degrees K
1324 m incand3000k =
1325 c
1326 cct 3000
1327 ed 1500
1328 .DE
1329 .SH
1330 SEE ALSO
1331 .LP
1332 .UL c,
1333 .UL cmix,
1334 .UL cspec,
1335 .UL cxy
1336 .ds RH CMIX
1337 .bp
1338 .SH
1339 NAME
1340 .LP
1341 cmix - mix two or more named colors to make the current color
1342 .SH
1343 SYNOPSIS
1344 .LP
1345 .B cmix
1346 .I "w1 c1 w2 c2 ..."
1347 .SH
1348 DESCRIPTION
1349 .LP
1350 The
1351 .UL cmix
1352 entity sums together two or more named colors using specified
1353 weighting coefficients, which correspond to the relative
1354 photometric brightness of each.
1355 As in all color specifications, the result is normalized so the
1356 absolute scale of the weights does not matter, only their relative
1357 values.
1358 .LP
1359 If any of the colors is a spectral quantity (i.e. from a
1360 .UL cspec
1361 or
1362 .UL cct
1363 entity), then all the colors are first converted to spectral
1364 quantities.
1365 This is done with an approximation for CIE (x,y) chromaticities,
1366 which may be problematic depending on their values.
1367 In general, it is safest to add together colors that are either
1368 all spectral quantities or all CIE quantities.
1369 .SH
1370 EXAMPLE
1371 .DS
1372 # Define RGB primaries for a standard color monitor
1373 c R =
1374 cxy 0.640 0.330
1375 c G =
1376 cxy 0.290 0.600
1377 c B =
1378 cxy 0.150 0.060
1379 # Mix them together in appropriate amounts for white
1380 c white =
1381 cmix 0.265 R 0.670 G 0.065 B
1382 .DE
1383 .SH
1384 SEE ALSO
1385 .LP
1386 .UL c,
1387 .UL cct,
1388 .UL cspec,
1389 .UL cxy
1390 .ds LH Material Entities
1391 .ds RH M
1392 .bp
1393 .SH
1394 NAME
1395 .LP
1396 m - get or set the current material context
1397 .SH
1398 SYNOPSIS
1399 .LP
1400 .B m
1401 [
1402 .I id
1403 [
1404 .B =
1405 [
1406 .I template
1407 ]
1408 ]
1409 ]
1410 .SH
1411 DESCRIPTION
1412 .LP
1413 If the
1414 .UL m
1415 keyword is given by itself, then it establishes
1416 the unnamed material context, which is a perfect two-sided black absorber.
1417 This context may be modified, but the changes will not be saved.
1418 .LP
1419 If the keyword is followed by an identifier
1420 .I id,
1421 then it reestablishes a previous context.
1422 If the specified context was never defined, an error will result.
1423 .LP
1424 If the entity is given with an identifier
1425 followed by an equals sign ('='), then a new context is established,
1426 and cleared to the default material.
1427 (Note that the equals sign must be separated from other
1428 arguments by white space to be properly recognized.)\0
1429 If the equals sign is followed by a second identifier
1430 .I template,
1431 then this previously defined material will be used as a source of
1432 default values instead.
1433 This may be used to establish a material alias, or to modify an
1434 existing material and give it a new name.
1435 .LP
1436 The sum of the diffuse and specular reflectances and transmittances
1437 must not be greater than one (with no negative values, obviously).
1438 These values are assumed to be measured at normal incidence.
1439 If an index of refraction is given, this may modify the balance between
1440 diffuse and specular reflectance at other incident angles.
1441 If the
1442 material is one-sided (see
1443 .UL sides
1444 entity), then it may be a dielectric interface.
1445 In this case, the specular transmittance given is that which would be
1446 measured at normal incidence for a pane of the material 5 mm thick.
1447 This is important for figuring the actual transmittance for non-planar
1448 geometries assuming a uniformly absorbing medium.
1449 (Diffuse transmittance will not be affected by thickness.)\0
1450 If the index of
1451 refraction has an imaginary part, then the surface is a metal and this
1452 implies other properties as well.
1453 The default index of refraction is that of a vacuum, i.e. (1,0).
1454 .SH
1455 EXAMPLE
1456 .DS
1457 # Define a blue enamel paint
1458 m blue_enamel =
1459 c
1460 cxy 0.2771 0.2975
1461 rd 0.5011
1462 c
1463 rs 0.0100 0.0350
1464 # Assign blue_enamel to be the color of the south wall
1465 m swall_mat = blue_enamel
1466 # ...
1467 # South wall face
1468 m swall_mat
1469 f sv1 sv2 sv3 sv4
1470 .DE
1471 .SH
1472 SEE ALSO
1473 .LP
1474 .UL ed,
1475 .UL ir,
1476 .UL rd,
1477 .UL rs,
1478 .UL sides,
1479 .UL td,
1480 .UL ts
1481 .ds RH SIDES
1482 .bp
1483 .SH
1484 NAME
1485 .LP
1486 sides - set the number of sides for the current material
1487 .SH
1488 SYNOPSIS
1489 .LP
1490 .B sides
1491 {
1492 .B 1
1493 |
1494 .B 2
1495 }
1496 .SH
1497 DESCRIPTION
1498 .LP
1499 The
1500 .UL sides
1501 entity is used to set the number of sides for the current material.
1502 If a surface is two-sided, then it will appear
1503 identical when viewed from either the front or the back.
1504 If a surface is one-sided,
1505 then it appears invisible when viewed from the back side.
1506 This means
1507 that a transmitting object will affect the light coming in through the
1508 front surface and ignore the characteristics of the back surface,
1509 unless the index of refraction is set.
1510 If the index of refraction is set, then the object will act as a
1511 solid piece of dielectric material.
1512 In either case, the transmission properties of the exiting surface
1513 should be the same as the incident surface for the model to be
1514 physically valid.
1515 .LP
1516 The default number of sides is two.
1517 .SH
1518 EXAMPLE
1519 .DS
1520 # Describe a blue crystal ball
1521 m blue_crystal =
1522 ir 1.650000 0
1523 # Solid dielectrics must use one-sided materials
1524 sides 1
1525 c
1526 rs 0.0602 0
1527 c
1528 cxy 0.3127 0.2881
1529 ts 0.6425 0
1530 v sc =
1531 p 10 15 1.5
1532 sph sc .02
1533 .DE
1534 .SH
1535 SEE ALSO
1536 .LP
1537 .UL ed,
1538 .UL ir,
1539 .UL m,
1540 .UL rd,
1541 .UL rs,
1542 .UL td,
1543 .UL ts
1544 .ds RH RD
1545 .bp
1546 .SH
1547 NAME
1548 .LP
1549 rd - set the diffuse reflectance for the current material
1550 .SH
1551 SYNOPSIS
1552 .LP
1553 .B rd
1554 .I rho_d
1555 .SH
1556 DESCRIPTION
1557 .LP
1558 Set the diffuse reflectance for the current material to
1559 .I rho_d
1560 using the current color to determine the spectral characteristics.
1561 This is the fraction of visible light that is reflected from a
1562 surface equally in all directions according to Lambert's law, and is
1563 often called the "Lambertian component."
1564 Photometric reflectance is measured according to v(lambda)
1565 response function of the 1931 CIE standard 2
1566 degree observer, and assumes an equal-energy white light source.
1567 The value must be between zero and one, and may be further
1568 restricted by the luminosity of the selected color.
1569 (I.e. it is impossible to have a violet material with a photometric
1570 reflectance close to one since the eye is less sensitive in this part
1571 of the spectrum.)\0
1572 .LP
1573 The default diffuse reflectance is zero.
1574 .SH
1575 EXAMPLE
1576 .DS
1577 # An off-white paint with 70% reflectance
1578 m flat_white70 =
1579 c
1580 cxy .3632 .3420
1581 rd .70
1582 .DE
1583 .SH
1584 SEE ALSO
1585 .LP
1586 .UL c,
1587 .UL ed,
1588 .UL ir,
1589 .UL m,
1590 .UL rs,
1591 .UL sides,
1592 .UL td,
1593 .UL ts
1594 .ds RH TD
1595 .bp
1596 .SH
1597 NAME
1598 .LP
1599 td - set the diffuse transmittance for the current material
1600 .SH
1601 SYNOPSIS
1602 .LP
1603 .B td
1604 .I tau_d
1605 .SH
1606 DESCRIPTION
1607 .LP
1608 Set the diffuse transmittance for the current material to
1609 .I tau_d
1610 using the current color to determine the spectral characteristics.
1611 This is the fraction of visible light that is transmitted through a
1612 surface equally in all (transmitted) directions.
1613 Like reflectance, transmittance is measured according to the
1614 standard v(lambda) curve, and assumes an equal-energy white light source.
1615 It is probably not possible to create a material with a diffuse
1616 transmittance above 50%, since well-diffused light will be reflected
1617 as well.
1618 .LP
1619 The default diffuse transmittance is zero.
1620 .SH
1621 EXAMPLE
1622 .DS
1623 # Model a perfect spherical diffuser, i.e. light hitting \
1624 either side will be scattered equally in all directions
1625 m wonderland_diffuser =
1626 c
1627 td .5
1628 rd .5
1629 .DE
1630 .SH
1631 SEE ALSO
1632 .LP
1633 .UL c,
1634 .UL ed,
1635 .UL ir,
1636 .UL m,
1637 .UL rd,
1638 .UL rs,
1639 .UL sides,
1640 .UL ts
1641 .ds RH ED
1642 .bp
1643 .SH
1644 NAME
1645 .LP
1646 ed - set the diffuse emittance for the current material
1647 .SH
1648 SYNOPSIS
1649 .LP
1650 .B ed
1651 .I epsilon_d
1652 .SH
1653 DESCRIPTION
1654 .LP
1655 Set the diffuse emittance for the current material to
1656 .I epsilon_d
1657 lumens per square meter using the current color to determine the
1658 spectral characteristics.
1659 Note that this is emittance rather than exitance, and therefore
1660 does not include reflected or transmitted light, which is a function
1661 of the other material settings and the illuminated environment.
1662 .LP
1663 The total lumen output of a convex emitting object
1664 is the radiating area of that object multiplied by its emittance.
1665 Therefore, one can compute the appropriate
1666 .I epsilon_d
1667 value for an emitter by dividing the total lumen output by the
1668 radiating area (in square meters).
1669 .LP
1670 The default emittance is zero.
1671 .SH
1672 EXAMPLE
1673 .DS
1674 # A 100-watt incandescent bulb (1600 lumens) modeled as a sphere
1675 m
1676 c
1677 cct 3000
1678 ed 87712
1679 v cent =
1680 p 0 0 0
1681 sph cent .0381
1682 .DE
1683 .SH
1684 SEE ALSO
1685 .LP
1686 .UL c,
1687 .UL ir,
1688 .UL m,
1689 .UL rd,
1690 .UL rs,
1691 .UL sides,
1692 .UL td,
1693 .UL ts
1694 .ds RH RS
1695 .bp
1696 .SH
1697 NAME
1698 .LP
1699 rs - set the specular reflectance for the current material
1700 .SH
1701 SYNOPSIS
1702 .LP
1703 .B rs
1704 .I "rho_s alpha_r"
1705 .SH
1706 DESCRIPTION
1707 .LP
1708 Set the specular reflectance for the current material to
1709 .I rho_s
1710 using the current color to determine the spectral characteristics.
1711 The surface roughness parameter is set to
1712 .I alpha_r,
1713 which is the RMS height of surface variations over the
1714 autocorrelation distance (equivalent to RMS facet slope).
1715 A roughness value of zero means a perfectly smooth surface, and
1716 values greater than 0.2 are unusual.
1717 (See application notes section 6.1.2 for a comparison between the
1718 roughness parameter and Phong specular power.)\0
1719 .LP
1720 The default specular reflectance is zero.
1721 .SH
1722 EXAMPLE
1723 .DS
1724 # Define a slightly rough brass metallic surface
1725 m rough_brass =
1726 c
1727 cxy .3820 .4035
1728 # 30% specular, 9% diffuse
1729 rs .30 .08
1730 rd .09
1731 .DE
1732 .SH
1733 SEE ALSO
1734 .LP
1735 .UL c,
1736 .UL ed,
1737 .UL ir,
1738 .UL m,
1739 .UL rd,
1740 .UL sides,
1741 .UL td,
1742 .UL ts
1743 .ds RH TS
1744 .bp
1745 .SH
1746 NAME
1747 .LP
1748 ts - set the specular transmittance for the current material
1749 .SH
1750 SYNOPSIS
1751 .LP
1752 .B ts
1753 .I "tau_s alpha_t"
1754 .SH
1755 DESCRIPTION
1756 .LP
1757 Set the specular transmittance for the current material to
1758 .I tau_s
1759 using the current color to determine the spectral characteristics.
1760 The effective surface roughness is set to
1761 .I alpha_t.
1762 Rays will be transmitted with the same distribution as they would
1763 have been reflected with if this roughness value were given to the
1764 .UL rs
1765 entity.
1766 .LP
1767 The default specular transmittance is zero.
1768 .SH
1769 EXAMPLE
1770 .DS
1771 # Define a green glass material (58% transmittance)
1772 m glass =
1773 sides 2
1774 ir 1.52 0
1775 c
1776 rs 0.0725 0
1777 c
1778 cxy .23 .38
1779 ts 0.5815 0
1780 # Define an uncolored translucent plastic (40% transmittance)
1781 m translucent =
1782 sides 2
1783 ir 1.4 0
1784 c
1785 rs .045 0
1786 ts .40 .05
1787 .DE
1788 .SH
1789 SEE ALSO
1790 .LP
1791 .UL c,
1792 .UL ed,
1793 .UL ir,
1794 .UL m,
1795 .UL rd,
1796 .UL rs,
1797 .UL sides,
1798 .UL td
1799 .ds RH IR
1800 .bp
1801 .SH
1802 NAME
1803 .LP
1804 ir - set the complex index of refraction for the current material
1805 .SH
1806 SYNOPSIS
1807 .LP
1808 .B ir
1809 .I "n_real n_imag"
1810 .SH
1811 DESCRIPTION
1812 .LP
1813 Set the index of refraction for the current material to
1814 .I (n_real,n_imag).
1815 If the material is a dielectric (as opposed to metallic), then
1816 .I n_imag
1817 should be zero.
1818 For solid dielectric objects, the material should be made one-sided.
1819 If it is being used for thin objects, then a two-sided
1820 material is appropriate.
1821 (See the
1822 .UL sides
1823 entity.)\0
1824 .LP
1825 The default index of refraction is that of a vacuum, (1,0).
1826 .SH
1827 EXAMPLE
1828 .DS
1829 # Define polished aluminum material
1830 m polished_aluminum =
1831 # Complex index of refraction (from physics table)
1832 ir .770058 6.08351
1833 c
1834 rs .75 0
1835 .DE
1836 .SH
1837 SEE ALSO
1838 .LP
1839 .UL c,
1840 .UL ed,
1841 .UL m,
1842 .UL rd,
1843 .UL rs,
1844 .UL sides,
1845 .UL td,
1846 .UL ts
1847 .ds LH Vertex Entities
1848 .ds RH V
1849 .bp
1850 .SH
1851 NAME
1852 .LP
1853 v - get or set the current vertex context
1854 .SH
1855 SYNOPSIS
1856 .LP
1857 .B v
1858 [
1859 .I id
1860 [
1861 .B =
1862 [
1863 .I template
1864 ]
1865 ]
1866 ]
1867 .SH
1868 DESCRIPTION
1869 .LP
1870 If the
1871 .UL v
1872 keyword is given by itself, then it establishes
1873 the unnamed vertex context, which is the origin with no normal.
1874 This context may be modified, but the changes will not be saved.
1875 (The unnamed vertex is never used except as a source of default
1876 values since all geometric entities call their vertices by name.)\0
1877 .LP
1878 If the keyword is followed by an identifier
1879 .I id,
1880 then it reestablishes a previous context.
1881 If the specified context was never defined, an error will result.
1882 .LP
1883 If the entity is given with an identifier
1884 followed by an equals sign ('='), then a new context is established,
1885 and cleared to the default vertex (the origin).
1886 (Note that the equals sign must be separated from other
1887 arguments by white space to be properly recognized.)\0
1888 If the equals sign is followed by a second identifier
1889 .I template,
1890 then this previously defined vertex will be used as a source of
1891 default values instead.
1892 This may be used to establish a vertex alias, or to modify an
1893 existing vertex and give it a new name.
1894 .LP
1895 A non-zero vertex normal must be given for
1896 certain entities, specifically
1897 .UL ring
1898 and
1899 .UL torus
1900 require a normal direction.
1901 An
1902 .UL f
1903 entity will interpolate vertex normals if given, and
1904 use the polygon plane normal otherwise.
1905 See the
1906 .UL prism
1907 entry for an explanation of how it interprets and uses vertex
1908 normals.
1909 The other entities ignore vertex normals if present.
1910 .LP
1911 The actual position and normal direction for a vertex is determined
1912 at the time of use by a geometric entity.
1913 Specifically, the transformation in effect at the time the vertex is
1914 defined is irrelevant.
1915 The only transformation that matters is the one that is applied to
1916 the geometry itself.
1917 This prevents double-transformation of vertices and allows one set
1918 of vertices to be used for multiple purposes, e.g. the front and
1919 back sides of a drawer.
1920 .SH
1921 EXAMPLE
1922 .DS
1923 # Make a capped cylinder
1924 v end1 =
1925 p 0 0 0
1926 n 0 0 -1
1927 v end2 =
1928 p 0 0 1
1929 cyl end1 1.2 end2
1930 # Forgot normal for end2
1931 v end2
1932 n 0 0 1
1933 ring end1 0 1.2
1934 ring end2 0 1.2
1935 .DE
1936 .SH
1937 SEE ALSO
1938 .LP
1939 .UL cone,
1940 .UL cyl,
1941 .UL f,
1942 .UL n,
1943 .UL p,
1944 .UL prism,
1945 .UL ring,
1946 .UL sph,
1947 .UL torus
1948 .ds RH P
1949 .bp
1950 .SH
1951 NAME
1952 .LP
1953 p - set the point location for the current vertex
1954 .SH
1955 SYNOPSIS
1956 .LP
1957 .B p
1958 .I "px py pz"
1959 .SH
1960 DESCRIPTION
1961 .LP
1962 Set the 3-dimensional position for the current vertex to
1963 .I (px,py,pz).
1964 The actual position of the vertex will be determined by the
1965 transformation in effect at the time the vertex is applied to a
1966 geometric surface entity.
1967 The transform current when the position is set is irrelevant.
1968 .LP
1969 The default vertex position is the origin, (0,0,0).
1970 .SH
1971 EXAMPLE
1972 .DS
1973 # Make a small circle of 6 spheres
1974 v scent =
1975 p 1 0 0
1976 xf -a 6 -rz 60
1977 sph scent .05
1978 xf
1979 .DE
1980 .SH
1981 SEE ALSO
1982 .LP
1983 .UL cone,
1984 .UL cyl,
1985 .UL f,
1986 .UL n,
1987 .UL prism,
1988 .UL ring,
1989 .UL sph,
1990 .UL torus,
1991 .UL v
1992 .ds RH N
1993 .bp
1994 .SH
1995 NAME
1996 .LP
1997 n - set the surface normal direction for the current vertex
1998 .SH
1999 SYNOPSIS
2000 .LP
2001 .B n
2002 .I "dx dy dz"
2003 .SH
2004 DESCRIPTION
2005 .LP
2006 Set the 3-dimensional surface normal for the current vertex to the
2007 normalized vector along
2008 .I (dx,dy,dz).
2009 If this vector is zero, then the surface normal is effectively
2010 unset.
2011 The actual surface normal orientation of the vertex will be determined
2012 by the transformation in effect at the time the vertex is applied to a
2013 geometric surface entity.
2014 The current transform when the normal is set is irrelevant.
2015 .LP
2016 The default vertex normal is the zero vector (i.e. no normal).
2017 .SH
2018 EXAMPLE
2019 .DS
2020 # Make a chain of 10 interlocking doughnuts
2021 v tcent =
2022 p 0 0 0
2023 n 0 1 0
2024 xf -a 10 -rx 90 -t .2 0 0
2025 torus tcent .1 .2
2026 xf
2027 .DE
2028 .SH
2029 SEE ALSO
2030 .LP
2031 .UL f,
2032 .UL p,
2033 .UL prism,
2034 .UL ring,
2035 .UL torus,
2036 .UL v
2037 .ds LH Geometric Entities
2038 .ds RH F
2039 .bp
2040 .SH
2041 NAME
2042 .LP
2043 f - create an N-sided polygonal face
2044 .SH
2045 SYNOPSIS
2046 .LP
2047 .B f
2048 .I "v1 v2 ... vN"
2049 .SH
2050 DESCRIPTION
2051 .LP
2052 Create a polygonal face made of the current material
2053 by connecting the named vertices in order, and connecting the last
2054 vertex to the first.
2055 There must be at least three vertices, and if any vertex is undefined,
2056 an error will result.
2057 .LP
2058 The surface orientation is determined by the right-hand rule; when
2059 the curl of the fingers follows the given order of the vertices, the
2060 surface normal points in the thumb direction.
2061 Face vertices should be coplanar, though this is difficult to guarantee
2062 in a 3-dimensional specification.
2063 .LP
2064 If any vertices have associated surface normals, they will be used
2065 instead of the average plane normal, though it is safest to specify
2066 either all normals or no normals, and to stick with triangles
2067 when normals are used.
2068 Also, specified normals should point in the general direction of the
2069 surface for best results.
2070 .LP
2071 There is no explicit representation of holes in MGF. A hole must be
2072 represented implicitly by connecting vertices to form "seams." For
2073 example, a wall with a window in it might look as shown in Figure 1.
2074 In many systems, the wall itself would be represented with the first
2075 list of vertices, (v1,v2,v3,v4) and the hole associated with that
2076 wall as a second set of vertices (v5,v6,v7,v8). In MGF, we must
2077 give the whole thing as a single polygon, connecting the vertices so
2078 as to create a "seam," as shown in Figure 2.
2079 This could be written in MGF as "f v1 v2 v3 v4 v5 v6 v7 v8 v5 v4".
2080 .LP
2081 It is very important that the order of the hole be opposite to the
2082 order of the outer perimeter, otherwise the polygon will be
2083 "twisted" on top of itself. Note also that the seam was traversed
2084 in both directions, once going from v4 to v5, and again returning
2085 from v5 to v4. This is a necessary condition for a proper seam.
2086 .LP
2087 The choice of vertices to make into a seam is somewhat arbitrary, but
2088 some rendering systems may not give sane results if you cross over a
2089 hole with part of your seam. If we had chosen to create the seam
2090 between v2 and v5 in the above example instead of v4 and v5, the seam
2091 would cross our hole and may not render correctly\(dg.
2092 .FS
2093 \(dgFor systems that
2094 are sensitive to this, it is probably safest for their MGF
2095 loader/translator to re-expresses seams in terms of holes again, which can
2096 be done easily so long as vertices are shared in the fashion shown.
2097 .FE
2098 .bp
2099 Replace this page with the first page from "figures.ps".
2100 .bp
2101 .SH
2102 EXAMPLE
2103 .DS
2104 # Make a pyramid
2105 v apex =
2106 p 1 1 1
2107 v base0 =
2108 p 0 0 0
2109 v base1 =
2110 p 0 2 0
2111 v base2 =
2112 p 2 2 0
2113 v base3 =
2114 p 2 0 0
2115 # Bottom
2116 f base0 base1 base2 base3
2117 # Sides
2118 f base0 apex base1
2119 f base1 apex base2
2120 f base2 apex base3
2121 f base3 apex base0
2122 .DE
2123 .SH
2124 SEE ALSO
2125 .LP
2126 .UL cone,
2127 .UL cyl,
2128 .UL m,
2129 .UL prism,
2130 .UL ring,
2131 .UL sph,
2132 .UL torus,
2133 .UL v
2134 .ds RH SPH
2135 .bp
2136 .SH
2137 NAME
2138 .LP
2139 sph - create a sphere
2140 .SH
2141 SYNOPSIS
2142 .LP
2143 .B sph
2144 .I "vc rad"
2145 .SH
2146 DESCRIPTION
2147 .LP
2148 Create a sphere made of the current material with its center at the
2149 named vertex
2150 .I vc
2151 and a radius of
2152 .I rad.
2153 If the vertex is undefined an error will result.
2154 .LP
2155 The surface normal is usually directed outward, but will be directed
2156 inward if the given radius is negative.
2157 (This typically matters only for one-sided materials.)\0
2158 A zero radius is illegal.
2159 .SH
2160 EXAMPLE
2161 .DS
2162 # Create a thick glass sphere with a hollow inside
2163 m glass =
2164 sides 1
2165 ir 1.52 0
2166 c
2167 rs .06 0
2168 ts .88 0
2169 v cent =
2170 p 0 0 1.1
2171 # The outer shell
2172 sph cent .1
2173 # The inner bubble
2174 sph cent -.08
2175 .DE
2176 .SH
2177 SEE ALSO
2178 .LP
2179 .UL cone,
2180 .UL cyl,
2181 .UL f,
2182 .UL m,
2183 .UL prism,
2184 .UL ring,
2185 .UL torus,
2186 .UL v
2187 .ds RH CYL
2188 .bp
2189 .SH
2190 NAME
2191 .LP
2192 cyl - create an open-ended, truncated right cylinder
2193 .SH
2194 SYNOPSIS
2195 .LP
2196 .B cyl
2197 .I "v1 rad v2"
2198 .SH
2199 DESCRIPTION
2200 .LP
2201 Create a truncated right cylinder of radius
2202 .I rad
2203 using the current material, starting at the named vertex
2204 .I v1
2205 and continuing to
2206 .I v2.
2207 The ends will be open, but may be capped using the
2208 .UL ring
2209 entity if desired.
2210 .LP
2211 The surface normal will usually be directed outward, but may be
2212 directed inward by giving a negative value for
2213 .I rad.
2214 A zero radius is illegal, and
2215 .I v1
2216 cannot equal
2217 .I v2.
2218 .SH
2219 EXAMPLE
2220 .DS
2221 # A stylus with one rounded and one pointed end
2222 o stylus
2223 v vtip0 =
2224 p 0 0 0
2225 v vtip1 =
2226 p 0 0 .005
2227 v vend =
2228 p 0 0 .05
2229 cyl vtip1 .0015
2230 sph vend .0015
2231 cone vtip0 0 vtip1 .0015
2232 o
2233 .DE
2234 .SH
2235 SEE ALSO
2236 .LP
2237 .UL cone,
2238 .UL f,
2239 .UL m,
2240 .UL prism,
2241 .UL ring,
2242 .UL sph,
2243 .UL torus,
2244 .UL v
2245 .ds RH CONE
2246 .bp
2247 .SH
2248 NAME
2249 .LP
2250 cone - create an open-ended, truncated right cone
2251 .SH
2252 SYNOPSIS
2253 .LP
2254 .B cone
2255 .I "v1 rad1 v2 rad2"
2256 .SH
2257 DESCRIPTION
2258 .LP
2259 Create a truncated right cone using the current material.
2260 The starting radius is
2261 .I rad1
2262 at
2263 .I v1
2264 and the ending radius is
2265 is
2266 .I rad2
2267 at
2268 .I v2.
2269 The ends will be open, but may be capped using the
2270 .UL ring
2271 entity if desired.
2272 .LP
2273 The surface normal will usually be directed outward, but may be
2274 directed inward by giving negative values for both radii.
2275 (It is illegal for the signs of the two radii to disagree.)\0
2276 One but not both radii may be zero, indicating that the cone comes
2277 to a point.
2278 .LP
2279 Although it is not strictly forbidden to have equal cone radii, the
2280 .UL cyl
2281 entity should be used in such cases.
2282 Likewise, the
2283 .UL ring
2284 entity must be used if
2285 .I v1
2286 and
2287 .I v2
2288 are equal.
2289 .SH
2290 EXAMPLE
2291 .DS
2292 # A parasol
2293 o parasol
2294 v v1 =
2295 p 0 0 0
2296 v v2 =
2297 p 0 0 .75
2298 v v3 =
2299 p 0 0 .7
2300 m handle_mat
2301 cyl v1 .002 v2
2302 m parasol_paper
2303 cyl v2 0 v3 .33
2304 o
2305 .DE
2306 .SH
2307 SEE ALSO
2308 .LP
2309 .UL cyl,
2310 .UL f,
2311 .UL m,
2312 .UL prism,
2313 .UL ring,
2314 .UL sph,
2315 .UL torus,
2316 .UL v
2317 .ds RH PRISM
2318 .bp
2319 .SH
2320 NAME
2321 .LP
2322 prism - create a closed right prism
2323 .SH
2324 SYNOPSIS
2325 .LP
2326 .B prism
2327 .I "v1 v2 ... vN length"
2328 .SH
2329 DESCRIPTION
2330 .LP
2331 Create a closed right prism using the current material.
2332 One end face will be enclosed by the named vertices, and the
2333 opposite end face will be a mirror image at a distance
2334 .I length
2335 from the original.
2336 The edges will be extruded into N quadrilaterals connecting
2337 the two end faces.
2338 .LP
2339 The order of vertices determines the original face orientation
2340 according to the right-hand rule as explained for the
2341 .UL f
2342 entity.
2343 Normally, the prism is extruded in the direction opposite to the
2344 original surface normal, resulting in faces that all point outward.
2345 If the specified
2346 .I length
2347 is negative, the prism will be extruded above the original face
2348 and all surface normals will point inward.
2349 .LP
2350 If the vertices have associated normals, they are applied to the
2351 side faces only, and should generally point in the appropriate
2352 direction (i.e. in or out depending on whether
2353 .I length
2354 is negative or positive).
2355 .SH
2356 EXAMPLE
2357 .DS
2358 # Make a unit cube starting at the origin and \\\\
2359 extending to the positive octant
2360 v cv0 =
2361 p 0 0 0
2362 v cv1 =
2363 p 0 1 0
2364 v cv2 =
2365 p 1 1 0
2366 v cv3 =
2367 p 1 0 0
2368 # Right hand rule has original face looking in -Z direction
2369 prism cv0 cv1 cv2 cv3 1
2370 .DE
2371 .SH
2372 SEE ALSO
2373 .LP
2374 .UL cyl,
2375 .UL cone,
2376 .UL f,
2377 .UL m,
2378 .UL ring,
2379 .UL sph,
2380 .UL torus,
2381 .UL v
2382 .ds RH RING
2383 .bp
2384 .SH
2385 NAME
2386 .LP
2387 ring - create a circular ring with inner and outer radii
2388 .SH
2389 SYNOPSIS
2390 .LP
2391 .B cyl
2392 .I "vc rmin rmax"
2393 .SH
2394 DESCRIPTION
2395 .LP
2396 Create a circular face of the current material centered on the named
2397 vertex
2398 .I vc
2399 with an inner radius of
2400 .I rmin
2401 and an outer radius of
2402 .I rmax.
2403 The surface orientation is determined by the normal vector
2404 associated with
2405 .I vc.
2406 If this vertex is undefined or has no normal, an error will result.
2407 The minimum radius may be equal to but not less than zero, and the
2408 maximum radius must be strictly greater than the minimum.
2409 .SH
2410 EXAMPLE
2411 .DS
2412 # The proverbial brass ring
2413 o brass_ring
2414 m brass
2415 v end1 =
2416 p 0 -.005 0
2417 n 0 -1 0
2418 v end2 =
2419 p 0 .005 0
2420 n 0 1 0
2421 ring end1 .02 .03
2422 cyl end1 .03 end2
2423 ring end2 .02 .03
2424 cyl end2 -.02 end1
2425 o
2426 .DE
2427 .SH
2428 SEE ALSO
2429 .LP
2430 .UL cyl,
2431 .UL cone,
2432 .UL f,
2433 .UL m,
2434 .UL prism,
2435 .UL sph,
2436 .UL torus,
2437 .UL v
2438 .ds RH TORUS
2439 .bp
2440 .SH
2441 NAME
2442 .LP
2443 torus - create a regular torus
2444 .SH
2445 SYNOPSIS
2446 .LP
2447 .B torus
2448 .I "vc rmin rmax"
2449 .SH
2450 DESCRIPTION
2451 .LP
2452 Create a torus of the current material centered on the named vertex
2453 .I vc
2454 with an inner radius of
2455 .I rmin
2456 and an outer radius of
2457 .I rmax.
2458 The plane of the torus will be perpendicular to the normal vector
2459 associated with
2460 .I vc.
2461 If this vertex is undefined or has no normal, an error will result.
2462 .LP
2463 If a torus with an inward facing surface normal is desired,
2464 .I rmin
2465 and
2466 .I rmax
2467 may be negative.
2468 The minimum radius may be zero, but may not be negative when
2469 .I rmax
2470 is positive or vice versa.
2471 The magnitude or
2472 .I rmax
2473 must always be strictly greater than that of
2474 .I rmin.
2475 .SH
2476 EXAMPLE
2477 .DS
2478 # The proverbial brass ring -- easy grip version
2479 o brass_ring
2480 m brass
2481 v center =
2482 p 0 0 0
2483 n 0 1 0
2484 torus center .02 .03
2485 o
2486 .DE
2487 .SH
2488 SEE ALSO
2489 .LP
2490 .UL cyl,
2491 .UL cone,
2492 .UL f,
2493 .UL m,
2494 .UL prism,
2495 .UL ring,
2496 .UL sph,
2497 .UL v
2498 .ds RH
2499 .ds LH
2500 .bp
2501 .NH
2502 MGF Translators
2503 .LP
2504 Initially, there are four translators for MGF data, but only
2505 one of these is distributed with the MGF parser itself,
2506 .I mgfilt.
2507 Two of the other translators,
2508 .I mgf2rad
2509 and
2510 .I rad2mgf
2511 convert between MGF and the Radiance scene description language,
2512 and are distributed for free with the rest of the Radiance
2513 package\(dg.
2514 .FS
2515 \(dgRadiance is available by anonymous ftp from hobbes.lbl.gov and
2516 nestor.epfl.ch, or by WWW from
2517 "http://radsite.lbl.gov/radiance/HOME.html"
2518 .FE
2519 A third translator,
2520 .I mgf2meta,
2521 converts to a 2-dimensional line plot, and is also
2522 distributed with Radiance.
2523 .LP
2524 Mgfilt is a simple but useful utility that takes MGF on its input
2525 and produces MGF on its output.
2526 It uses the parser to convert entities that are not wanted or
2527 understood, and produces only the requested ones.
2528 This is useful for seeing what exactly a program must understand
2529 when it supports a given set of entities, and may serve as a
2530 substitute for linking to the parser library for programmers who
2531 wish to interpret the ASCII input directly but without all the
2532 unwanted entities.
2533 In future releases of MGF, this utility will also be handy for
2534 taking new entities and producing older versions of MGF for
2535 translators that have not yet been updated properly.
2536 .ds LH Translators
2537 .ds RH MGFILT
2538 .bp
2539 .SH
2540 NAME
2541 .LP
2542 mgfilt - get usable MGF entities from input
2543 .SH
2544 SYNOPSIS
2545 .LP
2546 .B mgfilt
2547 .B version
2548 [
2549 .B input ..
2550 ]
2551 .br
2552 or
2553 .br
2554 .B mgfilt
2555 .B "e1,e2,.."
2556 [
2557 .B input ..
2558 ]
2559 .SH
2560 DESCRIPTION
2561 .LP
2562 .I Mgfilt
2563 takes one or more MGF input files and converts all the entities to
2564 the types listed.
2565 In the first form, a single integer is given for the
2566 .I version
2567 of MGF that is to be produced.
2568 Since MGF is in its first major release, this is not yet a useful
2569 form, but it will be when the second major release comes out.
2570 .LP
2571 In the second form,
2572 .I mgfilt
2573 produces only the entities listed in the first argument, which must
2574 be comma-separated.
2575 The listed entity order is not important, but all entities given
2576 must be defined in the current version of MGF.
2577 Unknown entities will be summarily discarded on the input, and a
2578 warning message will be printed to the standard error.
2579 .SH
2580 EXAMPLES
2581 .LP
2582 To take an MGF version 3 file and send it to a version 2
2583 translator:
2584 .IP
2585 mgfilt 2 input.mgf | mgf2rad > input.rad
2586 .LP
2587 To take an MGF file and produce only flat polygonal faces
2588 with no materials:
2589 .IP
2590 mgfilt f,v,p,xf input.mgf > flatpoly.mgf
2591 .SH
2592 SEE ALSO
2593 .LP
2594 mgf2rad, rad2mgf
2595 .ds RH MGF2RAD
2596 .bp
2597 .SH
2598 NAME
2599 .LP
2600 mgf2rad - convert Materials and Geometry Format file to RADIANCE description
2601 .SH
2602 SYNOPSIS
2603 .LP
2604 .B mgf2rad
2605 [
2606 .B "\-m matfile"
2607 ][
2608 .B "\-e mult"
2609 ][
2610 .B "\-g dist"
2611 ]
2612 [
2613 .B input ..
2614 ]
2615 .SH
2616 DESCRIPTION
2617 .LP
2618 .I Mgf2rad
2619 converts one or more Materials and Geometry Format (MGF)
2620 files to a RADIANCE scene description.
2621 By definition, all output dimensions are in meters.
2622 The material names and properties
2623 for the surfaces will be those assigned in MGF.
2624 Any materials not defined in MGF will result in an error during
2625 translation.
2626 Light sources are described inline as IES luminaire files, and
2627 .I mgf2rad
2628 calls the program
2629 .I ies2rad(1)
2630 to translate these files.
2631 If an IES file in turn contains an MGF description of the local
2632 fixture geometry, this may result in a recursive call to
2633 .I mgf2rad,
2634 which is normal and should be transparent.
2635 The only side-effect of this additional translation is the
2636 appearance of other RADIANCE scene and data files produced
2637 automatically by
2638 .I ies2rad.
2639 .LP
2640 The
2641 .I \-m
2642 option may be used to put all the translated materials into a separate
2643 RADIANCE file.
2644 This is not always advisable, as any given material name may be
2645 reused at different points in the MGF description, and writing them
2646 to a separate file loses the contextual association between
2647 materials and surfaces.
2648 As long as unique material names are used throughout the MGF
2649 description and material properties are not redefined, there
2650 will be no problem.
2651 Note that this is the only way to get all the translated materials
2652 into a single file, since no output is produced for unreferenced
2653 materials; i.e. translating just the MGF materials does not work.
2654 .LP
2655 The
2656 .I \-e
2657 option may be used to multiply all the emission values by the
2658 given
2659 .I mult
2660 factor.
2661 The
2662 .I \-g
2663 option may be used to establish a glow distance (in meters)
2664 for all emitting surfaces.
2665 These two options are employed principally by
2666 .I ies2rad,
2667 and are not generally useful to most users.
2668 .SH
2669 EXAMPLES
2670 .LP
2671 To translate two MGF files into one RADIANCE materials file and
2672 one geometry file:
2673 .IP
2674 mgf2rad -m materials.rad building1.mgf building2.mgf > building1+2.rad
2675 .LP
2676 To create an octree directly from two MGF files and one RADIANCE
2677 file:
2678 .IP
2679 oconv '\\!mgf2rad materials.mgf scene.mgf' source.rad > scene.oct
2680 .SH
2681 FILES
2682 .LP
2683 tmesh.cal Used to smooth polygonal geometry
2684 .br
2685 *.rad RADIANCE source descriptions created by ies2rad
2686 .br
2687 *.dat RADIANCE source data created by ies2rad
2688 .br
2689 source.cal Used for IES source coordinates
2690 .SH
2691 AUTHOR
2692 .LP
2693 Greg Ward
2694 .SH
2695 SEE ALSO
2696 .LP
2697 ies2rad(1), mgf2meta(1), obj2rad(1), oconv(1), rad2mgf(1), xform(1)
2698 .ds RH
2699 RAD2MGF
2700 .bp
2701 .SH
2702 NAME
2703 .LP
2704 rad2mgf - convert RADIANCE scene description to Materials and Geometry Format
2705 .SH
2706 SYNOPSIS
2707 .LP
2708 .B rad2mgf
2709 [
2710 .B \-dU
2711 ]
2712 [
2713 .B input ..
2714 ]
2715 .SH
2716 DESCRIPTION
2717 .LP
2718 .I Rad2mgf
2719 converts one or more RADIANCE scene files
2720 to the Materials and Geometry Format (MGF).
2721 Input units are specified with the
2722 .I \-mU
2723 option, where
2724 .I U
2725 is one of 'm' (meters), 'c' (centimeters), 'f' (feet) or 'i'
2726 (inches).
2727 The assumed unit is meters, which is the required output unit for
2728 MGF (thus the need to know).
2729 If the input dimensions are in none of these units, then the user
2730 should apply
2731 .I xform(1)
2732 with the
2733 .I \-s
2734 option to bring the units into line prior to translation.
2735 .LP
2736 The MGF material names and properties
2737 for the surfaces will be those assigned in RADIANCE.
2738 If a referenced material has not been defined, then its name will
2739 be invoked in the MGF output without definition, and the description
2740 will be incomplete.
2741 .SH
2742 LIMITATIONS
2743 .LP
2744 Although MGF supports all of the geometric types and the most
2745 common material types used in RADIANCE, there is currently no
2746 support for advanced BRDF materials, patterns, textures or mixtures.
2747 Also, the special types "source" and "antimatter" are not supported,
2748 and all light source materials are converted to simple diffuse emitters
2749 (except "illum" materials, which are converted to their alternates).
2750 These primitives are reproduced as comments in the output and
2751 must be replaced manually if necessary.
2752 .LP
2753 The RADIANCE "instance" type is treated specially.
2754 .I Rad2mgf
2755 converts each instance to an MGF include statement, using the corresponding
2756 transformation and a file name derived from the octree name.
2757 (The original octree suffix is replaced by ".mgf".)\0
2758 For this to work, the user must separately create the referenced
2759 MGF files from the original RADIANCE descriptions.
2760 The description file names can usually be determined using the
2761 .I getinfo(1)
2762 command run on the octrees in question.
2763 .SH
2764 EXAMPLES
2765 .LP
2766 To convert three RADIANCE files (in feet) to one MGF file:
2767 .IP
2768 mgf2rad -df file1.rad file2.rad file3.rad > scene.mgf
2769 .LP
2770 To translate a RADIANCE materials file to MGF:
2771 .IP
2772 mgf2rad materials.rad > materials.mgf
2773 .SH
2774 AUTHOR
2775 .LP
2776 Greg Ward
2777 .SH
2778 SEE ALSO
2779 .LP
2780 getinfo(1), ies2rad(1), mgf2meta(1), mgf2rad(1), obj2rad(1), oconv(1), xform(1)
2781 .ds RH MGF2META
2782 .bp
2783 .SH
2784 NAME
2785 .LP
2786 mgf2meta - convert Materials and Geometry Format file to Metafile graphics
2787 .SH
2788 SYNOPSIS
2789 .LP
2790 .B mgf2meta
2791 [
2792 .B "-t threshold"
2793 ]
2794 .B "{x|y|z} xmin xmax ymin ymax zmin zmax"
2795 [
2796 .B input ..
2797 ]
2798 .SH
2799 DESCRIPTION
2800 .LP
2801 .I Mgf2meta
2802 converts one or more Materials and Geometry Format (MGF)
2803 files to a 2-D orthographic projection along the selected axis in the
2804 .I metafile(1)
2805 graphics format.
2806 All geometry is clipped to the specified bounding box, and the
2807 resulting orientation is as follows:
2808 .sp .5
2809 .nf
2810 Projection Orientation
2811 ======= ========
2812 x Y-axis right, Z-axis up
2813 y Z-axis right, X-axis up
2814 z X-axis right, Z-axis up
2815 .fi
2816 .LP
2817 If multiple input files are given, the first file prints in black,
2818 the second prints in red, the third in green and the fourth in blue.
2819 If more than four input files are given, they cycle through the
2820 colors again in three other line types: dashed, dotted and
2821 dot-dashed.
2822 .LP
2823 The
2824 .I \-t
2825 option may be used to randomly throw out line segments that are
2826 shorter than the given
2827 .I threshold
2828 (given as a fraction of the plot width).
2829 Segments are included with a
2830 probability equal to the square of the line length over the square
2831 of the threshold.
2832 This can greatly reduce the number of lines in the drawing (and
2833 therefore improve the drawing speed) with only a modest loss in
2834 quality.
2835 A typical value for this parameter is 0.005.
2836 .LP
2837 All MGF material information is ignored on the input.
2838 .SH
2839 EXAMPLES
2840 .LP
2841 To project two MGF files along the Z-axis and display them under
2842 X11:
2843 .IP
2844 mgf2meta z 0 10 0 15 0 9 building1.mgf building2.mgf | x11meta
2845 .LP
2846 To convert a RADIANCE scene to a line drawing in RADIANCE picture
2847 format:
2848 .IP
2849 rad2mgf scene.rad | mgf2meta x `getbbox -h scene.rad` | meta2tga |
2850 ra_t8 -r > scene.pic
2851 .SH
2852 AUTHOR
2853 .LP
2854 Greg Ward
2855 .SH
2856 SEE ALSO
2857 .LP
2858 getbbox(1), meta2tga(1), metafile(5), mgf2rad(1), pflip(1),
2859 protate(1), psmeta(1), ra_t8(1), rad2mgf(1), t4014(1), x11meta(1)
2860 .ds RH
2861 .ds LH
2862 .bp
2863 .NH
2864 MGF Parser Library
2865 .LP
2866 The principal motivation for creating a standard parser library for
2867 MGF is to make it easy for software developers to offer some base
2868 level of compliance.
2869 The key to making MGF easy to support in fact is the parser, which
2870 has the ability to express higher order entities in terms of
2871 lower order ones.
2872 For example, tori are part of the MGF specification, but if a given
2873 program or translator does not support them, the parser will convert
2874 them to cones.
2875 If cones are not supported either, it will convert them further into
2876 smoothed polygons.
2877 If smoothing (vertex normal information) is not supported, it will
2878 be ignored and the program will just get flat polygons.
2879 This is done in such a way that future versions of the standard may
2880 include new entities that old software does not even have to know
2881 about, and they will be converted appropriately.
2882 Forward compatibility is thus built right into the parser loading
2883 mechanism itself -- the programmer simply links to the new code and
2884 the new standard is supported without any further changes.
2885 .SH
2886 Language
2887 .LP
2888 The provided MGF parser is written in ANSI-C.
2889 This language was chosen for reasons of portability and efficiency.
2890 Almost all systems support some form of ANSI-compatible C, and many
2891 languages can cross-link to C libraries without modification.
2892 Backward compatibility to Kernighan and Ritchie C is achieved by
2893 compiling with the -DNOPROTO flag.
2894 .LP
2895 All of the data structures and prototypes needed for the library
2896 are in the header file "parser.h".
2897 This file is the best resource for the parser and is updated with
2898 each MGF release.
2899 .SH
2900 Mechanism
2901 .LP
2902 The parser works by a simple callback mechanism to routines that
2903 actually interpret the individual entities.
2904 Some of these routines will belong to the calling program, and some
2905 will be entity support routines included in the library itself.
2906 There is a global array of function pointers, called
2907 .I mg_ehand.
2908 It is defined thus:
2909 .DS
2910 extern int (*mg_ehand[MG_NENTITIES])(int argc, char **argv);
2911 .DE
2912 Before parsing begins, this dispatch table is initialized to point to the
2913 routines that will handle each supported entity.
2914 Every entity handler has the same basic prototype, which is the
2915 same as the
2916 .I main
2917 function, i.e:
2918 .DS
2919 extern int \f2handler\f1(int argc, char **argv);
2920 .DE
2921 The first argument is the number of words in the MGF entity
2922 (counting the entity itself) and the second argument is an array of
2923 nul-terminated strings with the entity and its arguments.
2924 The function should return zero or one of the error
2925 codes defined in "parser.h".
2926 A non-zero return value causes the parser to abort, returning the
2927 error up through its call stack to the entry function, usually
2928 .I mg_load.
2929 .LP
2930 A special function pointer for undefined entities is
2931 defined as follows:
2932 .DS
2933 extern int (*mg_uhand)(int argc, char **argv);
2934 .DE
2935 By default, this points to the library function
2936 .I mg_defuhand,
2937 which prints an error message on the first unknown entity and keeps a
2938 count from then on, which is stored in the global unsigned integer
2939 .I mg_nunknown.
2940 If the
2941 .I mg_uhand
2942 pointer is assigned a value of NULL instead, parsing will abort at the
2943 first unrecognized entity.
2944 The reason this is not the default action is that ignoring unknown entities
2945 offers a certain base level of forward compatibility.
2946 Ignoring things one does not understand is not the best approach, but it
2947 is usually better than quitting with an error message if the input is
2948 in fact valid, but is a later version of the standard.
2949 The real solution is to update the interpreter by linking to a new version
2950 of the parser, or use a new version of the
2951 .I mgfilt
2952 command to convert the new MGF input to an older standard.
2953 .LP
2954 The
2955 .I mg_uhand
2956 pointer may also be used to customize the language for a particular
2957 application by adding entities, though this is discouraged because it
2958 tends to weaken the standard.
2959 .LP
2960 The skeletal framework for an MGF loader or translator is to assign
2961 function pointers to the
2962 .I mg_ehand
2963 array, call the parser initialization function
2964 .I mg_init,
2965 then call the file loader function
2966 .I mg_load
2967 once for each input file.
2968 This will in turn make calls back to the functions assigned to
2969 .I mg_ehand.
2970 To give a simple example, let us look at a
2971 translator that understands only flat polygonal faces, putting out
2972 vertex locations immediately after each "face" keyword:
2973 .DS
2974 #include <stdio.h>
2975 #include "parser.h"
2976
2977 int
2978 myfaceh(ac, av) /* face handling routine */
2979 int ac;
2980 char **av;
2981 {
2982 C_VERTEX *vp; /* vertex structure pointer */
2983 FVECT vert; /* vertex point location */
2984 int i;
2985
2986 if (ac < 4) /* check # arguments */
2987 return(MG_EARGC);
2988 printf("face\n"); /* begin face output */
2989 for (i = 1; i < ac; i++) {
2990 if ((vp = c_getvert(av[i])) == NULL) /* vertex from name */
2991 return(MG_EUNDEF);
2992 xf_xfmpoint(vert, vp->p); /* apply transform */
2993 printf("%15.9f %15.9f %15.9f\n",
2994 vert[0], vert[1], vert[2]); /* output vertex */
2995 }
2996 printf(";\\n"); /* end of face output */
2997 return(MG_OK); /* normal exit */
2998 }
2999
3000 main(argc, argv) /* translate MGF file(s) */
3001 int argc;
3002 char **argv;
3003 {
3004 int i;
3005 /* initialize dispatch table */
3006 mg_ehand[MG_E_FACE] = myfaceh; /* ours */
3007 mg_ehand[MG_E_VERTEX] = c_hvertex; /* parser lib */
3008 mg_ehand[MG_E_POINT] = c_hvertex; /* parser lib */
3009 mg_ehand[MG_E_XF] = xf_handler; /* parser lib */
3010 mg_init(); /* initialize parser */
3011 for (i = 1; i < argc; i++) /* load each file argument */
3012 if (mg_load(argv[i]) != MG_OK) /* and check for error */
3013 exit(1);
3014 exit(0); /* all done! */
3015 }
3016 .DE
3017 Hopefully, this example demonstrates just how easy it is to
3018 write an MGF translator.
3019 Of course, translators get more complicated the more entity
3020 types they support, but the point is that one does not
3021 .I have
3022 to support every entity -- the parser handles what the translator
3023 does not.
3024 Also, the library includes many general entity handlers,
3025 further reducing the burden on the programmer.
3026 This same principle means that it is not necessary to modify an
3027 existing program to accommodate a new version of MGF -- one need only
3028 link to the new parser library to comply with the new standard.
3029 .SH
3030 Division of Labor
3031 .LP
3032 As seen in the previous example, there are two parser routines that
3033 are normally called directly in an MGF translator or loader program.
3034 The first is
3035 .I mg_init,
3036 which takes no arguments but relies on the program having
3037 initialized those parts of the global
3038 .I mg_ehand
3039 array it cares about.
3040 The second routine is
3041 .I mg_load,
3042 which is called once on each input file.
3043 (A third routine,
3044 .I mg_clear,
3045 may be called to free the parser data structures after each file or
3046 after all files, if the program plans to continue rather than
3047 exit.)\0
3048 .LP
3049 The rest of the routines in a translator or loader program are
3050 called indirectly through the
3051 .I mg_ehand
3052 dispatch table, and they are the ones that do the real work of
3053 supporting the MGF entities.
3054 In addition to converting or discarding entities that the calling
3055 program does not know or care about, the parser library includes a
3056 set of context handlers that greatly simplify the translation
3057 process.
3058 There are three handlers for each of the three named contexts and
3059 their constituents, and two handlers for the two hierarchical
3060 context entities.
3061 To use these handlers, one simply sets the appropriate positions in the
3062 .I mg_ehand
3063 dispatch table to point to these functions.
3064 Additional functions and global data structures provide convenient
3065 access to the relevant contexts, and all of these are detailed in
3066 the following manual pages.
3067 .ds LH Basic Parser Routines
3068 .ds RH MG_INIT
3069 .bp
3070 .SH
3071 NAME
3072 .LP
3073 mg_init, mg_ehand, mg_uhand - initialize MGF entity handlers
3074 .SH
3075 SYNOPSIS
3076 .LP
3077 #include "parser.h"
3078 .LP
3079 .B void
3080 mg_init(
3081 .B void
3082 )
3083 .LP
3084 .B int
3085 mg_defuhand(
3086 .B int
3087 argc,
3088 .B char
3089 **argv )
3090 .LP
3091 .B "extern int"
3092 (*mg_ehand[MG_NENTITIES])(
3093 .B int
3094 argc,
3095 .B char
3096 **argv )
3097 .LP
3098 .B "extern int"
3099 (*mg_uhand)(
3100 .B int
3101 argc,
3102 .B char
3103 **argv )
3104 .LP
3105 .B "extern unsigned"
3106 mg_nunknown
3107 .SH
3108 DESCRIPTION
3109 .LP
3110 The parser dispatch table,
3111 .I mg_ehand
3112 is initially set to all NULL pointers, and it
3113 is the duty of the calling program to assign entity handler functions to
3114 each of the supported entity positions in the array.
3115 The entities are given in the include file "parser.h" as the
3116 following:
3117 .DS
3118 #define MG_E_COMMENT 0 /* # */
3119 #define MG_E_COLOR 1 /* c */
3120 #define MG_E_CCT 2 /* cct */
3121 #define MG_E_CONE 3 /* cone */
3122 #define MG_E_CMIX 4 /* cmix */
3123 #define MG_E_CSPEC 5 /* cspec */
3124 #define MG_E_CXY 6 /* cxy */
3125 #define MG_E_CYL 7 /* cyl */
3126 #define MG_E_ED 8 /* ed */
3127 #define MG_E_FACE 9 /* f */
3128 #define MG_E_INCLUDE 10 /* i */
3129 #define MG_E_IES 11 /* ies */
3130 #define MG_E_IR 12 /* ir */
3131 #define MG_E_MATERIAL 13 /* m */
3132 #define MG_E_NORMAL 14 /* n */
3133 #define MG_E_OBJECT 15 /* o */
3134 #define MG_E_POINT 16 /* p */
3135 #define MG_E_PRISM 17 /* prism */
3136 #define MG_E_RD 18 /* rd */
3137 #define MG_E_RING 19 /* ring */
3138 #define MG_E_RS 20 /* rs */
3139 #define MG_E_SIDES 21 /* sides */
3140 #define MG_E_SPH 22 /* sph */
3141 #define MG_E_TD 23 /* td */
3142 #define MG_E_TORUS 24 /* torus */
3143 #define MG_E_TS 25 /* ts */
3144 #define MG_E_VERTEX 26 /* v */
3145 #define MG_E_XF 27 /* xf */
3146
3147 #define MG_NENTITIES 28 /* total # entities */
3148 .DE
3149 .LP
3150 Once the
3151 .I mg_ehand
3152 array has been set by the program, the
3153 .I mg_init
3154 routine must be called to complete the initialization process.
3155 This should be done once and only once per invocation, before any other
3156 parser routines are called.
3157 .LP
3158 The
3159 .I mg_uhand
3160 variable points to the current handler for unknown entities
3161 encountered on the input.
3162 Its default value points to the
3163 .I mg_defuhand
3164 function, which simply increments the global variable
3165 .I mg_nunknown,
3166 printing a warning message on the standard error on the first
3167 offense.
3168 (This message may be avoided by incrementing
3169 .I mg_nunknown
3170 before processing begins.)\0
3171 If
3172 .I mg_uhand
3173 is assigned a value of NULL, then an unknown entity will return an
3174 .I MG_EUNK
3175 error, which will cause the parser to abort.
3176 (See the
3177 .I mg_load
3178 page for a list of errors.)\0
3179 If the
3180 .I mg_uhand
3181 pointer is assigned to another function, that function will receive
3182 any unknown entities and their arguments, and the parsing will
3183 abort if the new function returns a non-zero error value.
3184 This offers a convenient way to customize the language by adding
3185 non-standard entities.
3186 .SH
3187 DIAGNOSTICS
3188 .LP
3189 If an inconsistent set of entities has been set for support, the
3190 .I mg_init
3191 routine will print an informative message to standard error and abort
3192 the calling program with a call to
3193 .I exit.
3194 This is normally unacceptable behavior for a library routine, but since
3195 such an error indicates a fault with the calling program itself,
3196 recovery is impossible.
3197 .SH
3198 SEE ALSO
3199 .LP
3200 mg_load, mg_handle
3201 .ds RH MG_LOAD
3202 .bp
3203 .SH
3204 NAME
3205 .LP
3206 mg_load, mg_clear, mg_file, mg_err - load MGF file, clear data structures
3207 .SH
3208 SYNOPSIS
3209 .LP
3210 #include "parser.h"
3211 .LP
3212 .B int
3213 mg_load(
3214 .B char
3215 *filename )
3216 .LP
3217 .B void
3218 mg_clear(
3219 .B void
3220 )
3221 .LP
3222 .B extern
3223 MG_FCTXT *mg_file
3224 .LP
3225 .B "extern char"
3226 *mg_err[MG_NERRS]
3227 .SH
3228 DESCRIPTION
3229 .LP
3230 The
3231 .I mg_load
3232 function loads the named file, or standard input if
3233 .I filename
3234 is the NULL pointer.
3235 Calls back to the appropriate MGF handler routines are made through the
3236 .I mg_ehand
3237 dispatch table.
3238 .LP
3239 The global
3240 .I mg_file
3241 variable points to the current file context structure, which
3242 may be useful for the interpretation of certain entities, such as
3243 .UL ies,
3244 which must know the directory path of the enclosing file.
3245 This structure is of the defined type
3246 .I MG_FCTXT,
3247 given in "parser.h" as:
3248 .DS
3249 typedef struct mg_fctxt {
3250 char fname[96]; /* file name */
3251 FILE *fp; /* stream pointer */
3252 int fid; /* unique file context id */
3253 char inpline[4096]; /* input line */
3254 int lineno; /* line number */
3255 struct mg_fctxt *prev; /* previous context */
3256 } MG_FCTXT;
3257 .DE
3258 .SH
3259 DIAGNOSTICS
3260 .LP
3261 If an error is encountered during parsing,
3262 .I mg_load
3263 will print an appropriate error message to the standard error stream
3264 and return one of the non-zero values from "parser.h" listed below:
3265 .DS
3266 #define MG_OK 0 /* normal return value */
3267 #define MG_EUNK 1 /* unknown entity */
3268 #define MG_EARGC 2 /* wrong number of arguments */
3269 #define MG_ETYPE 3 /* argument type error */
3270 #define MG_EILL 4 /* illegal argument value */
3271 #define MG_EUNDEF 5 /* undefined reference */
3272 #define MG_ENOFILE 6 /* cannot open input file */
3273 #define MG_EINCL 7 /* error in included file */
3274 #define MG_EMEM 8 /* out of memory */
3275 #define MG_ESEEK 9 /* file seek error */
3276 #define MG_EBADMAT 10 /* bad material specification */
3277
3278 #define MG_NERRS 11
3279 .DE
3280 If it is inappropriate to send output to standard error, the calling
3281 program should use the routines listed under
3282 .I mg_open
3283 for better control over the parsing process.
3284 .LP
3285 The
3286 .I mg_err
3287 array contains error messages corresponding to each of the values
3288 listed above in the native country's language.
3289 .SH
3290 SEE ALSO
3291 .LP
3292 mg_fgetpos, mg_handle, mg_init
3293 .ds RH MG_OPEN
3294 .bp
3295 .SH
3296 NAME
3297 .LP
3298 mg_open, mg_read, mg_parse, mg_close - MGF file loading subroutines
3299 .SH
3300 SYNOPSIS
3301 .LP
3302 #include "parser.h"
3303 .LP
3304 .B int
3305 mg_open( MG_FCTXT *fcp,
3306 .B char
3307 *filename )
3308 .LP
3309 .B int
3310 mg_read(
3311 .B void
3312 )
3313 .LP
3314 .B int
3315 mg_parse(
3316 .B void
3317 )
3318 .LP
3319 .B void
3320 mg_close(
3321 .B void
3322 )
3323 .SH
3324 DESCRIPTION
3325 .LP
3326 Most loaders and translators will call the
3327 .I mg_load
3328 routine to handle the above operations, but some programs or
3329 entity handlers require tighter control over the loading process.
3330 .LP
3331 The
3332 .I mg_open
3333 routine takes an uninitialized
3334 .I MG_FCTXT
3335 structure and a file name as its arguments.
3336 If
3337 .I filename
3338 is the NULL pointer, the standard input is "opened."
3339 The
3340 .I fcp
3341 structure will be set by
3342 .I mg_open
3343 prior to its return, and the global
3344 .I mg_file
3345 pointer will be assigned to point to it.
3346 This variable must not be destroyed until after the file is closed
3347 with a call to
3348 .I mg_close.
3349 (See the
3350 .I mg_load
3351 page for a definition of
3352 .I mg_file
3353 and the
3354 .I MG_FCTXT
3355 type.)\0
3356 .LP
3357 The
3358 .I mg_read
3359 function reads the next input line from the current file,
3360 returning the number of characters in the line, or zero if the
3361 end of file is reached or there is a file error.
3362 The function skips over escaped newlines, and keeps track of the
3363 line number in the current file context
3364 .I mg_file,
3365 which also contains the line that was read.
3366 .LP
3367 The
3368 .I mg_parse
3369 function breaks the current line in the
3370 .I mg_file
3371 structure into words and calls the appropriate handler routine, if
3372 any.
3373 Blank lines and unsupported entities cause a quick return.
3374 .LP
3375 The
3376 .I mg_close
3377 routine closes the current input file (unless it is the standard
3378 input) and returns to the previous file context (if any).
3379 .SH
3380 DIAGNOSTICS
3381 .LP
3382 The
3383 .I mg_open
3384 function returns
3385 .I MG_OK
3386 (0) normally, or
3387 .I MG_ENOFILE
3388 if the open fails for some reason.
3389 .LP
3390 The
3391 .I mg_parse
3392 function returns
3393 .I MG_OK
3394 if the current line was successfully interpreted, or one of the
3395 defined error values if there is a problem.
3396 (See the
3397 .I mg_load
3398 page for the defined error values.)\0
3399 .SH
3400 SEE ALSO
3401 .LP
3402 mg_fgetpos, mg_handle, mg_init, mg_load
3403 .ds RH MG_FGETPOS
3404 .bp
3405 .SH
3406 NAME
3407 .LP
3408 mg_fgetpos, mg_fgoto - get current file position and seek to pointer
3409 .SH
3410 SYNOPSIS
3411 .LP
3412 #include "parser.h"
3413 .LP
3414 .B void
3415 mg_fgetpos( MG_FPOS *pos )
3416 .LP
3417 .B int
3418 mg_fgoto( MG_FPOS *pos )
3419 .SH
3420 DESCRIPTION
3421 .LP
3422 The
3423 .I mg_fgetpos
3424 gets the current MGF file position and loads it into the passed
3425 .I MG_FPOS
3426 structure,
3427 .I pos.
3428 .LP
3429 The
3430 .I mg_fgoto
3431 function seeks to the position
3432 .I pos,
3433 taken from a previous call to
3434 .I mg_fgetpos.
3435 .SH
3436 DIAGNOSTICS
3437 .LP
3438 If
3439 .I mg_fgoto
3440 is passed an illegal pointer or one that does not correspond to the
3441 current
3442 .I mg_file
3443 context, it will return the
3444 .I MG_ESEEK
3445 error value.
3446 Normally, it returns
3447 .I MG_OK
3448 (0).
3449 .SH
3450 SEE ALSO
3451 .LP
3452 mg_load, mg_open
3453 .ds RH MG_HANDLE
3454 .bp
3455 .SH
3456 NAME
3457 .LP
3458 mg_handle, mg_entity, mg_ename, mg_nqcdivs - entity assistance and control
3459 .SH
3460 SYNOPSIS
3461 .LP
3462 .B int
3463 mg_handle(
3464 .B int
3465 en,
3466 .B int
3467 ac,
3468 .B char
3469 *av )
3470 .LP
3471 .B int
3472 mg_entity(
3473 .B char
3474 *name )
3475 .LP
3476 .B "extern char"
3477 mg_ename[MG_NENTITIES][MG_MAXELEN]
3478 .LP
3479 .B "extern int"
3480 mg_nqcdivs
3481 .SH
3482 DESCRIPTION
3483 .LP
3484 The
3485 .I mg_handle
3486 routine may be used to pass entities back to the parser
3487 to be redirected through the
3488 .I mg_ehand
3489 dispatch table.
3490 This method is recommended rather than calling through
3491 .I mg_ehand
3492 directly, since the parser sometimes has its own support routines
3493 that it needs to call for specific entities.
3494 The first argument,
3495 .I en,
3496 is the corresponding entity number, or -1 if
3497 .I mg_handle
3498 should figure it out from the first
3499 .I av
3500 argument.
3501 .LP
3502 The
3503 .I mg_entity
3504 function gets an entity number from its name, using a hash
3505 table on the
3506 .I mg_ename
3507 list.
3508 .LP
3509 The
3510 .I mg_ename
3511 table contains the string names corresponding to each MGF entity in
3512 the designated order.
3513 (See the
3514 .I mg_init
3515 page for the list of MGF entities.)\0
3516 .LP
3517 The global integer variable
3518 .I mg_nqcdivs
3519 tells the parser how many subdivisions to use per quarter circle (90
3520 degrees) when tesselating curved geometry.
3521 The default value is 5, and it may be reset at any time by the
3522 calling program.
3523 .SH
3524 DIAGNOSTICS
3525 .LP
3526 The
3527 .I mg_handle
3528 function returns
3529 .I MG_OK
3530 if the entity is handled correctly, or one of the predefined error
3531 values if there is a problem.
3532 (See the
3533 .I mg_load
3534 page for a list of error values.)\0
3535 .LP
3536 The
3537 .I mg_entity
3538 function returns -1 if the passed name does not appear in the
3539 .I mg_ename
3540 list.
3541 .SH
3542 SEE ALSO
3543 .LP
3544 mg_init, mg_load, mg_open
3545 .ds RH ISINT, ISFLT, ISNAME
3546 .bp
3547 .SH
3548 NAME
3549 .LP
3550 isint, isflt, isname - determine if string fits integer or real format,
3551 or is legal identifier
3552 .SH
3553 SYNOPSIS
3554 .LP
3555 .B int
3556 isint(
3557 .B char
3558 *str )
3559 .LP
3560 .B int
3561 isflt(
3562 .B char
3563 *str )
3564 .LP
3565 .B int
3566 isname(
3567 .B char
3568 *str )
3569 .SH
3570 DESCRIPTION
3571 .LP
3572 The
3573 .I isint
3574 function checks to see if the passed string
3575 .I str
3576 matches a decimal integer format (positive or negative),
3577 and returns 1 or 0 based on whether it does or does not.
3578 .LP
3579 The
3580 .I isflt
3581 function checks to see if the passed string
3582 .I str
3583 matches a floating point format (positive or negative with optional
3584 exponent), and returns 1 or 0 based on whether it does or does not.
3585 .LP
3586 The
3587 .I isname
3588 function checks to see if the passed string
3589 .I str
3590 is a legal identifier name.
3591 In MGF, a legal identifier must begin with a letter and contain only
3592 visible ASCII characters (those between decimal 33 and 127 inclusive).
3593 The one caveat to this is that names may begin with one or more
3594 underscores ('_'), but this is a trick employed by the parser to
3595 maintain a separate name space from the user, and is not legal usage
3596 otherwise.
3597 .LP
3598 Note that a string that matches an integer format is also a valid
3599 floating point value.
3600 Conversely, a string that is not a floating point number cannot be a
3601 valid integer.
3602 .LP
3603 These routines are useful for checking arguments passed to entity
3604 handlers that certain types in certain positions.
3605 If an invalid argument is passed, the handler should return an
3606 .I MG_ETYPE
3607 error.
3608 .SH
3609 SEE ALSO
3610 .LP
3611 mg_init, mg_load
3612 .ds LH Entity Support Routines
3613 .ds RH C_HVERTEX
3614 .bp
3615 .SH
3616 NAME
3617 .LP
3618 c_hvertex, c_getvert, c_cvname, c_cvertex - vertex entity support
3619 .SH
3620 SYNOPSIS
3621 .LP
3622 #include "parser.h"
3623 .LP
3624 .B int
3625 c_hvertex(
3626 .B int
3627 argc,
3628 .B char
3629 **argv )
3630 .LP
3631 C_VERTEX *c_getvert(
3632 .B char
3633 *name )
3634 .LP
3635 .B "extern char"
3636 *c_vname
3637 .LP
3638 .B extern
3639 C_VERTEX *c_cvertex
3640 .SH
3641 DESCRIPTION
3642 .LP
3643 The
3644 .I c_hvertex
3645 function handles the MGF vertex entities,
3646 .UL v,
3647 .UL p
3648 and
3649 .UL n.
3650 If either
3651 .UL p
3652 or
3653 .UL n
3654 is supported, then
3655 .UL v
3656 must be also.
3657 The assignments are normally made to the
3658 .I mg_ehand
3659 array prior to parser initialization, like so:
3660 .DS
3661 mg_ehand[MG_E_VERTEX] = c_hvertex; /* support "v" entity */
3662 mg_ehand[MG_E_POINT] = c_hvertex; /* support "p" entity */
3663 mg_ehand[MG_E_NORMAL] = c_hvertex; /* support "n" entity */
3664 /* other entity handler assignments... */
3665 mg_init(); /* initialize parser */
3666 .DE
3667 If vertex normals are not understood by any of the program-supported
3668 entities, then the
3669 .I MG_E_NORMAL
3670 entry may be left with its original NULL assignment.
3671 .LP
3672 The
3673 .I c_getvert
3674 call takes the name of a defined vertex and returns a pointer to its
3675 .I C_VERTEX
3676 structure, defined in "parser.h" as:
3677 .DS
3678 typedef FLOAT FVECT[3]; /* a 3-d real vector */
3679
3680 typedef struct {
3681 int clock; /* incremented each change -- resettable */
3682 FVECT p, n; /* point and normal */
3683 } C_VERTEX; /* vertex context */
3684 .DE
3685 The
3686 .I clock
3687 member will be incremented each time the value gets changed by a
3688 .UL p
3689 or
3690 .UL n
3691 entity, and may be reset by the controlling program if desired.
3692 This is a convenient way to keep track of whether or not a vertex has
3693 changed since its last use.
3694 To link identical vertices, one must also check that the current
3695 transform has not changed, which is uniquely identified by the
3696 global
3697 .I xf_context->xid
3698 variable, but only if one is using the parser libraries transform
3699 handler.
3700 (See the
3701 .I xf_handler
3702 page.)\0
3703 .LP
3704 It is possible but not recommended to alter the contents of the
3705 vertex structure returned by
3706 .I c_getvert.
3707 Normally it is read during the
3708 interpretation of entities using named vertices.
3709 .LP
3710 The name of the current vertex is given by the global
3711 .I c_cvname
3712 variable, which is set to NULL if the unnamed vertex is current.
3713 The current vertex value is pointed to by the global variable
3714 .I c_cvertex,
3715 which should never be NULL.
3716 .SH
3717 DIAGNOSTICS
3718 .LP
3719 The
3720 .I c_hvertex
3721 function returns
3722 .I MG_OK
3723 (0) if the vertex is handled correctly, or one of the predefined
3724 error values if there is a problem.
3725 (See the
3726 .I mg_load
3727 page for a list of errors.)\0
3728 .LP
3729 The
3730 .I c_getvert
3731 function returns NULL if the specified vertex name is undefined, at
3732 which point the calling function should return an
3733 .I MG_EUNDEF
3734 error.
3735 .SH
3736 SEE ALSO
3737 .LP
3738 c_hcolor, c_hmaterial, mg_init, mg_load, xf_handler
3739 .ds RH C_HCOLOR
3740 .bp
3741 .SH
3742 NAME
3743 .LP
3744 c_hcolor, c_getcolor, c_ccname, c_ccolor, c_ccvt, c_isgrey -
3745 color entity support
3746 .SH
3747 SYNOPSIS
3748 .LP
3749 #include "parser.h"
3750 .LP
3751 .B int
3752 c_hcolor(
3753 .B int
3754 argc,
3755 .B char
3756 **argv )
3757 .LP
3758 C_COLOR *c_getcolor(
3759 .B char
3760 *name )
3761 .LP
3762 .B "extern char"
3763 *c_ccname
3764 .LP
3765 .B extern
3766 C_COLOR *c_ccolor
3767 .LP
3768 .B void
3769 c_ccvt( C_COLOR *cvp,
3770 .B int
3771 cflags )
3772 .LP
3773 .B int
3774 c_isgrey( C_COLOR *cvp )
3775 .SH
3776 DESCRIPTION
3777 .LP
3778 The
3779 .I c_hcolor
3780 function supports the MGF entities,
3781 .UL c,
3782 .UL cxy,
3783 .UL cspec,
3784 .UL cct
3785 and
3786 .UL cmix.
3787 It is an error to support any of the color field entities without
3788 supporting the
3789 .UL c
3790 entity itself.
3791 The assignments are normally made to the
3792 .I mg_ehand
3793 array prior to parser initialization, like so:
3794 .DS
3795 mg_ehand[MG_E_COLOR] = c_hcolor; /* support "c" entity */
3796 mg_ehand[MG_E_CXY] = c_hcolor; /* support "cxy" entity */
3797 mg_ehand[MG_E_CSPEC] = c_hcolor; /* support "cspec" entity */
3798 mg_ehand[MG_E_CCT] = c_hcolor; /* support "cct" entity */
3799 mg_ehand[MG_E_CMIX] = c_hcolor; /* support "cmix" entity */
3800 /* other entity handler assignments... */
3801 mg_init(); /* initialize parser */
3802 .DE
3803 If the loader/translator has no use for spectral data, the entries for
3804 .UL cspec
3805 and
3806 .UL cct
3807 may be left with their original NULL assignments and these entities will
3808 be re-expressed appropriately as tristimulus values.
3809 .LP
3810 The
3811 .I c_getcolor
3812 function takes the name of a defined color and returns a pointer to its
3813 .I C_COLOR
3814 structure, defined in "parser.h" as:
3815 .DS
3816 #define C_CMINWL 380 /* minimum wavelength */
3817 #define C_CMAXWL 780 /* maximum wavelength */
3818 #define C_CNSS 41 /* number of spectral samples */
3819 #define C_CWLI ((C_CMAXWL-C_CMINWL)/(C_CNSS-1))
3820 #define C_CMAXV 10000 /* nominal maximum sample value */
3821 #define C_CLPWM (683./C_CMAXV) /* peak lumens/watt multiplier */
3822
3823 typedef struct {
3824 int clock; /* incremented each change */
3825 short flags; /* what's been set */
3826 short ssamp[C_CNSS]; /* spectral samples, min wl to max */
3827 long ssum; /* straight sum of spectral values */
3828 float cx, cy; /* xy chromaticity value */
3829 float eff; /* efficacy (lumens/watt) */
3830 } C_COLOR; /* color context */
3831 .DE
3832 The
3833 .I clock
3834 member will be incremented each time the value gets changed by a
3835 color field entity, and may be reset by the calling program if
3836 desired.
3837 This is a convenient way to keep track of whether or not a color has
3838 changed since its last use.
3839 The
3840 .I flags
3841 member indicates which color representations have been assigned,
3842 and is an inclusive OR of one or more of the following:
3843 .DS
3844 #define C_CSSPEC 01 /* flag if spectrum is set */
3845 #define C_CDSPEC 02 /* flag if defined w/ spectrum */
3846 #define C_CSXY 04 /* flag if xy is set */
3847 #define C_CDXY 010 /* flag if defined w/ xy */
3848 #define C_CSEFF 020 /* flag if efficacy set */
3849 .DE
3850 .LP
3851 It is possible but not recommended to alter the contents of the
3852 color structure returned by
3853 .I c_getcolor.
3854 Normally, this routine is never called directly, since there are no
3855 entities that access colors by name other than
3856 .UL c.
3857 .LP
3858 The global variable
3859 .I c_ccname
3860 points to the name of the current color, or NULL if it is unnamed.
3861 The variable
3862 .I c_ccolor
3863 points to the current color value, which should never be NULL.
3864 .LP
3865 The
3866 .I c_ccvt
3867 routine takes a
3868 .I C_COLOR
3869 structure and a set of desired flag settings and computes the
3870 missing color representation(s).
3871 .LP
3872 The
3873 .I c_isgrey
3874 function returns 1 if the passed color is very close to neutral
3875 grey, or 0 otherwise.
3876 .SH
3877 DIAGNOSTICS
3878 .LP
3879 The
3880 .I c_hcolor
3881 function returns
3882 .I MG_OK
3883 (0) if the color is handled correctly, or one of the predefined
3884 error values if there is a problem.
3885 (See the
3886 .I mg_load
3887 page for a list of errors.)\0
3888 .LP
3889 The
3890 .I c_getcolor
3891 function returns NULL if the specified color name is undefined, at
3892 which point the calling function should return an
3893 .I MG_EUNDEF
3894 error.
3895 .SH
3896 SEE ALSO
3897 .LP
3898 c_hmaterial, c_hvertex, mg_init, mg_load
3899 .ds RH C_HMATERIAL
3900 .bp
3901 .SH
3902 NAME
3903 .LP
3904 c_hmaterial, c_getmaterial, c_cmname, c_cmaterial -
3905 material entity support
3906 .SH
3907 SYNOPSIS
3908 .LP
3909 #include "parser.h"
3910 .LP
3911 .B int
3912 c_hmaterial(
3913 .B int
3914 argc,
3915 .B char
3916 **argv )
3917 .LP
3918 C_MATERIAL *c_getmaterial(
3919 .B char
3920 *name )
3921 .LP
3922 .B "extern char"
3923 *c_cmname
3924 .LP
3925 .B extern
3926 C_MATERIAL *c_cmaterial
3927 .SH
3928 DESCRIPTION
3929 .LP
3930 The
3931 .I c_hmaterial
3932 function supports the MGF entities,
3933 .UL m,
3934 .UL ed,
3935 .UL ir,
3936 .UL rd,
3937 .UL rs,
3938 .UL sides,
3939 .UL td,
3940 and
3941 .UL ts.
3942 It is an error to support any of the material field entities without
3943 supporting the
3944 .UL m
3945 entity itself.
3946 The assignments are normally made to the
3947 .I mg_ehand
3948 array prior to parser initialization, like so:
3949 .DS
3950 mg_ehand[MG_E_MATERIAL] = c_hmaterial; /* support "m" entity */
3951 mg_ehand[MG_E_ED] = c_hmaterial; /* support "ed" entity */
3952 mg_ehand[MG_E_IR] = c_hmaterial; /* support "ir" entity */
3953 mg_ehand[MG_E_RD] = c_hmaterial; /* support "rd" entity */
3954 mg_ehand[MG_E_RS] = c_hmaterial; /* support "rs" entity */
3955 mg_ehand[MG_E_SIDES] = c_hmaterial; /* support "sides" entity */
3956 mg_ehand[MG_E_TD] = c_hmaterial; /* support "td" entity */
3957 mg_ehand[MG_E_TS] = c_hmaterial; /* support "ts" entity */
3958 /* other entity handler assignments... */
3959 mg_init(); /* initialize parser */
3960 .DE
3961 Any of the above entities besides
3962 .UL m
3963 may be unsupported, but the parser will not attempt to include their
3964 effect into other members, e.g. an unsupported
3965 .UL rs
3966 component will not be added back into the
3967 .UL rd
3968 member.
3969 It is therefore safer to support all of the relevant material
3970 entities and make final approximations from the complete
3971 .I C_MATERIAL
3972 structure.
3973 .LP
3974 The
3975 .I c_getmaterial
3976 function takes the name of a defined material and returns a pointer to its
3977 .I C_MATERIAL
3978 structure, defined in "parser.h" as:
3979 .DS
3980 #define C_1SIDEDTHICK 0.005 /* assumed thickness of 1-sided mat. */
3981
3982 typedef struct {
3983 int clock; /* incremented each change -- resettable */
3984 int sided; /* 1 if surface is 1-sided, 0 for 2-sided */
3985 float nr, ni; /* index of refraction, real and imaginary */
3986 float rd; /* diffuse reflectance */
3987 C_COLOR rd_c; /* diffuse reflectance color */
3988 float td; /* diffuse transmittance */
3989 C_COLOR td_c; /* diffuse transmittance color */
3990 float ed; /* diffuse emittance */
3991 C_COLOR ed_c; /* diffuse emittance color */
3992 float rs; /* specular reflectance */
3993 C_COLOR rs_c; /* specular reflectance color */
3994 float rs_a; /* specular reflectance roughness */
3995 float ts; /* specular transmittance */
3996 C_COLOR ts_c; /* specular transmittance color */
3997 float ts_a; /* specular transmittance roughness */
3998 } C_MATERIAL; /* material context */
3999 .DE
4000 The
4001 .I clock
4002 member will be incremented each time the value gets changed by a
4003 material field entity, and may be reset by the calling program if
4004 desired.
4005 This is a convenient way to keep track of whether or not a material has
4006 changed since its last use.
4007 .LP
4008 All reflectance and transmittance values correspond to normal
4009 incidence, and may vary as a function of angle depending on the
4010 index of refraction.
4011 A solid object is normally represented with a one-sided material.
4012 A two-sided material is most appropriate for thin surfaces, though
4013 it may be used also when the surface normal orientations in a model
4014 are unreliable.
4015 .LP
4016 If a transparent or translucent surface is one-sided, then the
4017 absorption will change as a function of distance through the
4018 material, and a single value for diffuse or specular transmittance is
4019 ambiguous.
4020 We therefore define a standard thickness,
4021 .I C_1SIDEDTHICK,
4022 which is the object thickness to which the given values correspond,
4023 so that one may compute the isotropic absorptance of the material.
4024 .LP
4025 It is possible but not recommended to alter the contents of the
4026 material structure returned by
4027 .I c_getmaterial.
4028 Normally, this routine is never called directly, since there are no
4029 entities that access materials by name other than
4030 .UL m.
4031 .LP
4032 The global variable
4033 .I c_cmname
4034 points to the name of the current material, or NULL if it is unnamed.
4035 The variable
4036 .I c_cmaterial
4037 points to the current material value, which should never be NULL.
4038 .SH
4039 DIAGNOSTICS
4040 .LP
4041 The
4042 .I c_hmaterial
4043 function returns
4044 .I MG_OK
4045 (0) if the color is handled correctly, or one of the predefined
4046 error values if there is a problem.
4047 (See the
4048 .I mg_load
4049 page for a list of errors.)\0
4050 .LP
4051 The
4052 .I c_getmaterial
4053 function returns NULL if the specified material name is undefined, at
4054 which point the calling function should return an
4055 .I MG_EUNDEF
4056 error.
4057 .SH
4058 SEE ALSO
4059 .LP
4060 c_hcolor, c_hvertex, mg_init, mg_load
4061 .ds RH OBJ_HANDLER
4062 .bp
4063 .SH
4064 NAME
4065 .LP
4066 obj_handler, obj_clear, obj_nnames, obj_name - object name support
4067 .SH
4068 SYNOPSIS
4069 .LP
4070 .B int
4071 obj_handler(
4072 .B int
4073 argc,
4074 .B char
4075 **argv )
4076 .LP
4077 .B void
4078 obj_clear(
4079 .B void
4080 )
4081 .LP
4082 .B "extern int"
4083 obj_nnames
4084 .LP
4085 .B "extern char"
4086 **obj_name
4087 .SH
4088 DESCRIPTION
4089 .LP
4090 The
4091 .I obj_handler
4092 routine should be assigned to the
4093 .I MG_E_OBJECT
4094 entry of the parser's
4095 .I mg_ehand
4096 array prior to calling
4097 .I mg_load
4098 if the loader/translator wishes to support hierarchical object
4099 names.
4100 .LP
4101 The
4102 .I obj_clear
4103 function may be used to clear the object name stack and free any
4104 associated memory, but this is usually not necessary since
4105 .UL o
4106 begin and end entities are normally balanced in the input.
4107 .LP
4108 The global
4109 .I obj_nnames
4110 variable indicates the number of names currently in the object
4111 stack, and the
4112 .I obj_name
4113 list contains the name strings in the same order as they were
4114 encountered on the input.
4115 (I.e. the most recently pushed name is last.)\0
4116 .SH
4117 DIAGNOSTICS
4118 .LP
4119 The
4120 .I obj_handler
4121 function returns
4122 .I MG_OK
4123 (0) if the color is handled correctly, or one of the predefined
4124 error values if there is a problem.
4125 (See the
4126 .I mg_load
4127 page for a list of errors.)\0
4128 .SH
4129 SEE ALSO
4130 .LP
4131 mg_init, mg_load, xf_handler
4132 .ds RH XF_HANDLER
4133 .bp
4134 .SH
4135 NAME
4136 .LP
4137 xf_handler, xf_clear, xf_context, xf_argend - transformation support
4138 .SH
4139 SYNOPSIS
4140 .LP
4141 .B int
4142 xf_handler(
4143 .B int
4144 argc,
4145 .B char
4146 **argv )
4147 .LP
4148 .B void
4149 xf_clear(
4150 .B void
4151 )
4152 .LP
4153 .B extern
4154 XF_SPEC *xf_context
4155 .LP
4156 .B "extern char"
4157 **xf_argend
4158 .SH
4159 DESCRIPTION
4160 .LP
4161 The
4162 .I xf_handler
4163 routine should be assigned to the
4164 .I MG_E_XF
4165 entry of the parser's
4166 .I mg_ehand
4167 array prior to calling
4168 .I mg_load
4169 if the loader/translator wishes to support hierarchical
4170 transformations.
4171 (Note that all MGF geometric entities require this support.)\0
4172 .LP
4173 The
4174 .I xf_clear
4175 function may be used to clear the transform stack and free any
4176 associated memory, but this is usually not necessary since
4177 .UL xf
4178 begin and end entities are normally balanced in the input.
4179 .LP
4180 The global
4181 .I xf_context
4182 variable points to the current transformation context, which is of
4183 the type
4184 .I XF_SPEC,
4185 described in "parser.h":
4186 .DS
4187 typedef struct xf_spec {
4188 long xid; /* unique transform id */
4189 short xac; /* context argument count */
4190 short rev; /* boolean true if vertices reversed */
4191 XF xf; /* cumulative transformation */
4192 struct xf_array *xarr; /* transformation array pointer */
4193 struct xf_spec *prev; /* previous transformation context */
4194 } XF_SPEC; /* followed by argument buffer */
4195 .DE
4196 The
4197 .I xid
4198 member is a identifier associated with this transformation,
4199 which should be the same for identical transformations, as an aid to
4200 vertex sharing.
4201 (See also the
4202 .I c_hvertex
4203 page.)\0
4204 The
4205 .I xac
4206 member indicates the total number of transform arguments, and is
4207 used to indicate the position of the first argument relative to the
4208 last one pointed to by the global
4209 .I xf_argend
4210 variable.
4211 .LP
4212 The first transform argument starts at
4213 .I xf_argv,
4214 which is a macro defined in "parser.h" as:
4215 .DS
4216 #define xf_argv (xf_argend - xf_context->xac)
4217 .DE
4218 Note that accessing this macro will result in a segmentation violation
4219 if the current context is NULL, so one should first test the second macro
4220 .I xf_argc
4221 against zero.
4222 This macro is defined as:
4223 .DS
4224 #define xf_argc (xf_context==NULL ? 0 : xf_context->xac)
4225 .DE
4226 .LP
4227 Normally, neither of these macros will be used, since there are
4228 routines for transforming points, vectors and scalars directly based
4229 on the current transformation context.
4230 (See the
4231 .I xf_xfmpoint
4232 page for details.)\0
4233 .LP
4234 The
4235 .I rev
4236 member of the
4237 .I XF_SPEC
4238 structure indicates whether or not this transform reverses the order
4239 of polygon vertices.
4240 This member will be 1 if the transformation mirrors about an odd
4241 number of coordinate axes, thus inverting faces.
4242 The usual thing to do in this circumstance is to interpret the
4243 vertex arguments in the reverse order, so as to bring the face back
4244 to its original orientation in the new position.
4245 .LP
4246 The
4247 .I xf
4248 member contains the transformation scalefactor (in xf.sca)
4249 and 4x4 homogeneous matrix (in xf.xfm), but these will usually not
4250 be accessed directly.
4251 Likewise, the
4252 .I xarr
4253 and
4254 .I prev
4255 members point to data that should not be needed by the calling
4256 program.
4257 .SH
4258 DIAGNOSTICS
4259 .LP
4260 The
4261 .I xf_handler
4262 function returns
4263 .I MG_OK
4264 (0) if the color is handled correctly, or one of the predefined
4265 error values if there is a problem.
4266 (See the
4267 .I mg_load
4268 page for a list of errors.)\0
4269 .SH
4270 SEE ALSO
4271 .LP
4272 mg_init, mg_load, obj_handler, xf_xfmpoint
4273 .ds RH XF_XFMPOINT
4274 .bp
4275 .SH
4276 NAME
4277 .LP
4278 xf_xfmpoint xf_xfmvect, xf_rotvect, xf_scale - apply current
4279 transformation
4280 .SH
4281 SYNOPSIS
4282 .LP
4283 .B void
4284 xf_xfmpoint( FVECT pnew, FVECT pold )
4285 .LP
4286 .B void
4287 xf_xfmvect( FVECT vnew, FVECT vold )
4288 .LP
4289 .B void
4290 xf_rotvect( FVECT nnew, FVECT nold )
4291 .LP
4292 .B double
4293 xf_scale(
4294 .B double
4295 sold )
4296 .SH
4297 DESCRIPTION
4298 .LP
4299 The
4300 .I xf_xfmpoint
4301 routine applies the current transformation defined by
4302 .I xf_context
4303 to the point
4304 .I pold,
4305 scaling, rotating and moving it to its proper location, which is put in
4306 .I pnew.
4307 (The two arguments may point to the same vector.)\0
4308 .LP
4309 The
4310 .I xf_xfmvect
4311 routine applies the current transformation to the vector
4312 .I vold,
4313 scaling and rotating it to its proper location, which is put in
4314 .I vnew.
4315 (The two arguments may point to the same vector.)\0
4316 The only difference between
4317 .I xf_xfmpoint
4318 and
4319 .I xf_xfmvect
4320 is that in the latter, the final translation is not applied.
4321 .LP
4322 The
4323 .I xf_rotvect
4324 routine rotates the vector
4325 .I nold
4326 using the current transformation, and stores the result in
4327 .I nnew.
4328 (The two arguments may point to the same vector.)\0
4329 No translation or scaling is applied, which is the appropriate
4330 action for surface normal vectors for example.
4331 .LP
4332 The
4333 .I xf_scale
4334 function takes a scalar argument
4335 .I sold
4336 and applies the current scale factor, returning the result.
4337 .SH
4338 SEE ALSO
4339 .LP
4340 xf_handler
4341 .ds LH
4342 .ds RH
4343 .bp
4344 .NH
4345 Application Notes
4346 .NH 2
4347 Relation to Standard Practices in Computer Graphics
4348 .LP
4349 For those coming from a computer graphics background, some of the
4350 choices in the material model may seem strange or even capricious.
4351 Why not simply stick with RGB colors and a Phong specular component
4352 like everyone else?
4353 What is the point in choosing the number of sides to a material?
4354 .LP
4355 In the real world, a surface can have only one side,
4356 defining the interface between one volume and another.
4357 Many object-space rendering packages (e.g. z-buffer algorithms) take
4358 advantage of this fact by culling back-facing polygons and thus saving
4359 as much as 50% of the preprocessing time.
4360 However, many models rely on an
4361 approximation whereby a single surface is used to represent a very thin
4362 volume, such as a pane of glass, and this also can provide significant
4363 calculational savings in an image-space algorithm (such as
4364 ray-tracing).
4365 Also, many models are created in such a way that the front vs. back
4366 information is lost or confused, so that the back side of one or
4367 more surfaces may have to serve as the front side during rendering.
4368 (AutoCAD is one easily identified culprit in this department.)\0
4369 Since both types of surface models are useful and any
4370 rendering algorithm may ultimately be applied, MGF provides a way
4371 to specify sidedness rather than picking one interpretation or the other.
4372 .LP
4373 The problem with RGB is that there is no accepted standard, and even
4374 if we were to set one it would either be impossible to realize (i.e.
4375 impossible to create phosphors with the chosen colors) or it would
4376 have a gamut that excludes many saturated colors.
4377 The CIE color system was very carefully conceived and developed,
4378 and is the standard to which all photometric measurements adhere.
4379 It is therefore the logical choice in any standard format, though it
4380 has been too often ignored by the computer graphics community.
4381 .LP
4382 Regarding Phong shading, this was never a physical model and making it
4383 behave basic laws of reciprocity and energy balance is difficult.
4384 More to the point, specular power has almost nothing to do with
4385 surface microstructure, and is difficult to set properly
4386 even if every physical characteristic of a material has
4387 been carefully measured.
4388 This is the ultimate indictment of any physical model -- that it
4389 is incapable of reproducing any measurement whatsoever.
4390 .LP
4391 Admittedly, the compliment of diffuse and specular component plus
4392 surface roughness and index of refraction used in MGF is less than a
4393 perfect model, but it is serviceable for most materials and
4394 relatively simple to incorporate into a rendering algorithm.
4395 In the long term, MGF shall probably include full spectral
4396 scattering functions, though the sheer quantity of data involved
4397 makes this burdensome from both the measurement side and the
4398 simulation side.
4399 .NH 3
4400 Converting between Phong Specular Power and Gaussian Roughness
4401 .LP
4402 So-called specular reflection and transmission are modeled using a
4403 Gaussian distribution of surface facets.
4404 The roughness parameters to the
4405 .UL rs
4406 and
4407 .UL ts
4408 entities specify
4409 the root-mean-squared (RMS) surface facet slope, which varies from 0
4410 for a perfectly smooth surface to around .2 for a fairly rough one.
4411 The effect this will have on the reflected component distribution is
4412 well-defined, but predicting the behavior of the transmitted
4413 component requires further assumptions.
4414 We assume that the surface
4415 scatters light passing through it just as much as it scatters
4416 reflected light.
4417 This assumption is approximately correct for a
4418 two-sided transparent material with an index of refraction of 1.5
4419 (like glass) and both sides having the given RMS facet slope.
4420 .LP
4421 Oftentimes, one is translating from a Phong exponent on the cosine
4422 of the half-vector-to-normal angle to the more physical but less
4423 familiar Gaussian model of MGF.
4424 The hardest part is translating the specular power to a roughness value.
4425 For this, we recommend the following approximation:
4426 .IP
4427 roughness = 0.6/sqrt(specular_power)
4428 .LP
4429 It is not a perfect correlation, but it is about as close as one can get.
4430 .NH 3
4431 Converting between RGB and CIE Colors
4432 .LP
4433 Unlike most graphics languages, MGF does not use an RGB color model,
4434 simply because there is no recognized definition for this model.
4435 It is based on computer monitor phosphors, which vary from one
4436 CRT to the next.
4437 (There is an RGB standard defined in the TV
4438 industry, but this has a rather poor correlation to most computer
4439 monitors and it is impossible to express many real-world colors
4440 within its limited gamut.)\0
4441 .LP
4442 MGF uses two alternative, well-defined standards, spectral power
4443 distributions and the 1931 CIE 2 degree standard observer.
4444 With the CIE standard, any viewable
4445 color may be exactly represented as an (x,y) chromaticity value.
4446 Unfortunately, the interaction between
4447 colors (i.e. colored light sources and interreflections) cannot be
4448 specified exactly with any finite coordinate set, including CIE
4449 chromaticities.
4450 So, MGF offers the ability to give reflectance,
4451 transmittance or emittance as a function of wavelength over the visible
4452 spectrum.
4453 This function is still discretized, but at a user-selectable
4454 resolution.
4455 Furthermore, spectral colors may be mixed, providing (nearly)
4456 arbitrary basis functions, which can produce more accurate results in
4457 some cases and are merely a convenience for translation in others.
4458 .LP
4459 Conversion back and forth between CIE chromaticity coordinates and spectral
4460 samples is provided within the MGF parser.
4461 Unfortunately, conversion
4462 to and from RGB values depends on a particular RGB definition, and as we
4463 have said, there is no recognized standard.
4464 We therefore recommend that
4465 you decide yourself what chromaticity values to use for each RGB primary,
4466 and adopt the following code to convert between CIE and RGB coordinates.
4467 .LP
4468 .nf
4469 #ifdef NTSC
4470 #define CIE_x_r 0.670 /* standard NTSC primaries */
4471 #define CIE_y_r 0.330
4472 #define CIE_x_g 0.210
4473 #define CIE_y_g 0.710
4474 #define CIE_x_b 0.140
4475 #define CIE_y_b 0.080
4476 #define CIE_x_w 0.3333 /* monitor white point */
4477 #define CIE_y_w 0.3333
4478 #else
4479 #define CIE_x_r 0.640 /* nominal CRT primaries */
4480 #define CIE_y_r 0.330
4481 #define CIE_x_g 0.290
4482 #define CIE_y_g 0.600
4483 #define CIE_x_b 0.150
4484 #define CIE_y_b 0.060
4485 #define CIE_x_w 0.3333 /* monitor white point */
4486 #define CIE_y_w 0.3333
4487 #endif
4488
4489 #define CIE_D ( CIE_x_r*(CIE_y_g - CIE_y_b) + \\\\
4490 CIE_x_g*(CIE_y_b - CIE_y_r) + \\\\
4491 CIE_x_b*(CIE_y_r - CIE_y_g) )
4492 #define CIE_C_rD ( (1./CIE_y_w) * \\\\
4493 ( CIE_x_w*(CIE_y_g - CIE_y_b) - \\\\
4494 CIE_y_w*(CIE_x_g - CIE_x_b) + \\\\
4495 CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g ) )
4496 #define CIE_C_gD ( (1./CIE_y_w) * \\\\
4497 ( CIE_x_w*(CIE_y_b - CIE_y_r) - \\\\
4498 CIE_y_w*(CIE_x_b - CIE_x_r) - \\\\
4499 CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r ) )
4500 #define CIE_C_bD ( (1./CIE_y_w) * \\\\
4501 ( CIE_x_w*(CIE_y_r - CIE_y_g) - \\\\
4502 CIE_y_w*(CIE_x_r - CIE_x_g) + \\\\
4503 CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r ) )
4504
4505 #define CIE_rf (CIE_y_r*CIE_C_rD/CIE_D)
4506 #define CIE_gf (CIE_y_g*CIE_C_gD/CIE_D)
4507 #define CIE_bf (CIE_y_b*CIE_C_bD/CIE_D)
4508
4509 float xyz2rgbmat[3][3] = { /* XYZ to RGB */
4510 {(CIE_y_g - CIE_y_b - CIE_x_b*CIE_y_g + CIE_y_b*CIE_x_g)/CIE_C_rD,
4511 (CIE_x_b - CIE_x_g - CIE_x_b*CIE_y_g + CIE_x_g*CIE_y_b)/CIE_C_rD,
4512 (CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g)/CIE_C_rD},
4513 {(CIE_y_b - CIE_y_r - CIE_y_b*CIE_x_r + CIE_y_r*CIE_x_b)/CIE_C_gD,
4514 (CIE_x_r - CIE_x_b - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r)/CIE_C_gD,
4515 (CIE_x_b*CIE_y_r - CIE_x_r*CIE_y_b)/CIE_C_gD},
4516 {(CIE_y_r - CIE_y_g - CIE_y_r*CIE_x_g + CIE_y_g*CIE_x_r)/CIE_C_bD,
4517 (CIE_x_g - CIE_x_r - CIE_x_g*CIE_y_r + CIE_x_r*CIE_y_g)/CIE_C_bD,
4518 (CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r)/CIE_C_bD}
4519 };
4520
4521 float rgb2xyzmat[3][3] = { /* RGB to XYZ */
4522 {CIE_x_r*CIE_C_rD/CIE_D,CIE_x_g*CIE_C_gD/CIE_D,CIE_x_b*CIE_C_bD/CIE_D},
4523 {CIE_y_r*CIE_C_rD/CIE_D,CIE_y_g*CIE_C_gD/CIE_D,CIE_y_b*CIE_C_bD/CIE_D},
4524 {(1.-CIE_x_r-CIE_y_r)*CIE_C_rD/CIE_D,
4525 (1.-CIE_x_g-CIE_y_g)*CIE_C_gD/CIE_D,
4526 (1.-CIE_x_b-CIE_y_b)*CIE_C_bD/CIE_D}
4527 };
4528
4529
4530 cie_rgb(rgbcolor, ciecolor) /* convert CIE to RGB */
4531 register float *rgbcolor, *ciecolor;
4532 {
4533 register int i;
4534
4535 for (i = 0; i < 3; i++) {
4536 rgbcolor[i] = xyz2rgbmat[i][0]*ciecolor[0] +
4537 xyz2rgbmat[i][1]*ciecolor[1] +
4538 xyz2rgbmat[i][2]*ciecolor[2] ;
4539 if (rgbcolor[i] < 0.0) /* watch for negative values */
4540 rgbcolor[i] = 0.0;
4541 }
4542 }
4543
4544
4545 rgb_cie(ciecolor, rgbcolor) /* convert RGB to CIE */
4546 register float *ciecolor, *rgbcolor;
4547 {
4548 register int i;
4549
4550 for (i = 0; i < 3; i++)
4551 ciecolor[i] = rgb2xyzmat[i][0]*rgbcolor[0] +
4552 rgb2xyzmat[i][1]*rgbcolor[1] +
4553 rgb2xyzmat[i][2]*rgbcolor[2] ;
4554 }
4555 .fi
4556 .LP
4557 An alternative to adopting the above code is to use the MGF "cmix"
4558 entity to convert from RGB directly by naming the three primaries in
4559 terms of their chromaticities, e.g:
4560 .DS
4561 c R =
4562 cxy 0.640 0.330
4563 c G =
4564 cxy 0.290 0.600
4565 c B =
4566 cxy 0.150 0.060
4567 .DE
4568 .LP
4569 Then, converting from RGB to MGF colors is as simple as multiplying each
4570 component by its relative luminance in a cmix statement, for instance:
4571 .DS
4572 c white =
4573 cmix 0.265 R 0.670 G 0.065 B
4574 .DE
4575 .LP
4576 For the chosen RGB standard, the above specification would result a pure
4577 white.
4578 The reason the coefficients are not all 1 as you might expect is
4579 that cmix uses relative luminance as the standard for its weights.
4580 Since
4581 blue is less luminous for the same energy than red, which is in turn
4582 less luminous than green, the weights cannot be the same to achieve an
4583 even spectral balance.
4584 Unfortunately, computing these relative weights
4585 is not straightforward, though it is given in the above macros as CIE_rf,
4586 CIE_gf and CIE_bf.
4587 (The common factors in these macros may of course
4588 be removed since
4589 .UL cmix
4590 weights are all relative.)\0
4591 Alternatively, one could measure the actual full scale luminance of
4592 the phosphors with a luminance probe and get the same relative
4593 values.
4594 .NH 2
4595 Relation to IESNA LM-63 and Luminaire Catalogs
4596 .LP
4597 Recently, the Illuminating Engineering Society of North America
4598 (IESNA) adopted MGF as the official standard for
4599 representing luminaire geometry and materials.
4600 The way this works in an IES luminaire data file is through the
4601 addition of a keyword called LUMINOUSGEOMETRY, which is given on a
4602 line in the header portion of a file (before the TILT specification)
4603 like so:
4604 .LP
4605 .B [LUMINOUSGEOMETRY]
4606 .I mgf_file
4607 .LP
4608 The given MGF file must exist relative to the directory containing
4609 the IES file (i.e. the same stipulations and restrictions on pathnames
4610 apply as for the MGF
4611 .UL i
4612 entity).
4613 Furthermore, the position of the MGF geometry must be
4614 such that the gross geometric specification of emitting surfaces
4615 in the IES file completely
4616 blocks or encloses the luminous portions of the MGF description.
4617 Specifically, any ray traced towards the MGF geometry must strike
4618 the IES gross geometry before it strikes any luminous surface in the
4619 MGF description.
4620 This provides a convenient way of preventing overcounting in the
4621 illumination calculation, while still allowing for accurate fixture
4622 appearance.
4623 .LP
4624 To give two examples, let us consider first a recessed can, followed
4625 by a hanging direct/indirect fluorescent fixture.
4626 .LP
4627 The most appropriate IES geometric specification for the emitting
4628 area of a can light would be a circular disk.
4629 Since the IES gross geometry gives only the diameter of the disk, the
4630 actual 3-dimensional placement is implicitly defined as having a
4631 center at the origin, with the radiating disk facing in the
4632 negative Z direction (nadir, downwards).
4633 The MGF geometry would then be placed such that any luminous portion
4634 was above this disk, and no portion of it would obstruct the IES
4635 geometry.
4636 The most sensible position therefore has the IES disk flush with the
4637 MGF can opening, as shown in Figure 3.
4638 .bp
4639 Replace this page with the second page from "figures.ps".
4640 .bp
4641 .LP
4642 In the case of a direct/indirect fluorescent fixture, light will
4643 exit both the top and the bottom sides, and the IES geometry must
4644 enclose the radiating portion of the fixture entirely.
4645 It is acceptable to have additional MGF geometry above the
4646 fixture so long as it does not radiate, which is what we must do if
4647 we wish to include the support rods, as shown in Figure 4.
4648 .LP
4649 Note that the origin is always in the exact center of the IES
4650 geometry.
4651 .LP
4652 Not all fixtures will fit the simple IES geometry specification so
4653 nicely.
4654 For odd-shaped fixtures, it may be necessary to use an IES geometry
4655 that does not match the radiating area terribly well in order that
4656 it completely block or enclose the required MGF specification.
4657 .LP
4658 The unit of length in the MGF file is always meters, regardless of
4659 the units specified in the enclosing IES file.
4660 However, any and all multipliers applied to the candlepower data in the
4661 IES file will also be applied to the emittance of surfaces in the
4662 MGF specification, so that one MGF file may serve similar
4663 luminaires that differ in their total output.
4664 .NH
4665 Credits
4666 .LP
4667 The MGF language grew out of a joint investigation into physical
4668 representations for rendering undertaken by the author
4669 (Greg Ward of LBL) and Holly Rushmeier of the National
4670 Institute of Standards and Technology.
4671 After deciding that a complete and robust specification was
4672 an extreme challenge, we shelved the project for another time.
4673 A few months later, the author spoke with Ian Ashdown and Robert
4674 Shakespeare, who are both members of the IES Computing Committee,
4675 about the need for extending the existing data standard to
4676 include luminaire geometry and near-field photometry.
4677 We then moved forward as a team towards a somewhat less ambitious
4678 approach to physical materials and geometry that had the advantage
4679 of simplicity and the possibility of support with a standard parser
4680 library.
4681 The author went to work over the next two months
4682 on the detailed design of the language
4683 and an ANSI-C parser, with regular feedback from the other three
4684 team members.
4685 Several months and several versions later, we arrived at release
4686 1.0, which is the occasion of this document's creation.
4687 .LP
4688 Funding for this work... would be nice.