ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgfdoc.tr
Revision: 1.20
Committed: Fri Feb 28 20:11:29 2003 UTC (21 years, 2 months ago) by greg
Content type: application/x-troff
Branch: MAIN
CVS Tags: rad5R4, rad5R2, rad4R2P2, rad5R0, rad5R1, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R5, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1, rad5R3, HEAD
Changes since 1.19: +1 -1 lines
Log Message:
Updates for 3.5 release

File Contents

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