ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgfdoc.tr
Revision: 1.15
Committed: Fri Apr 5 16:35:25 1996 UTC (28 years, 1 month ago) by greg
Content type: application/x-troff
Branch: MAIN
Changes since 1.14: +1 -1 lines
Log Message:
corrected specular power conversion

File Contents

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