ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgfdoc.tr
Revision: 1.16
Committed: Tue Mar 18 11:43:22 1997 UTC (27 years, 1 month ago) by greg
Content type: application/x-troff
Branch: MAIN
Changes since 1.15: +64 -4 lines
Log Message:
added fh entity and general cleanup

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