ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgfdoc.tr
Revision: 1.2
Committed: Fri May 12 21:42:42 1995 UTC (29 years ago) by greg
Content type: application/x-troff
Branch: MAIN
Changes since 1.1: +14 -10 lines
Log Message:
fixed minor problems

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