1 /*
2     Copyright (c) 2008-2009 NetAllied Systems GmbH
3 
4     This file is part of MayaDataModel.
5 
6     Licensed under the MIT Open Source License,
7     for details please see LICENSE file or the website
8     http://www.opensource.org/licenses/mit-license.php
9 */
10 #ifndef __MayaDM_TYPES_H__
11 #define __MayaDM_TYPES_H__
12 
13 #include <assert.h>
14 #include <string>
15 #include <vector>
16 
17 // from ogre OgrePlatform.h
18 // Win32 compilers use _DEBUG for specifying debug builds.
19 // Unlike the Win32 compilers, Linux compilers seem to use DEBUG for when
20 // specifying a debug build.
21 // (??? this is wrong, on Linux debug builds aren't marked in any way unless
22 // you mark it yourself any way you like it -- zap ???)
23 #if defined(_DEBUG) || defined(DEBUG)
24 #     define MAYADM_DEBUG
25 #endif
26 
27 #if defined(MAYADM_DEBUG)
28 #	define MAYADM_ASSERT(cond) assert(cond);
29 #else
30 #	define MAYADM_ASSERT(cond)
31 #endif
32 
33 namespace MayaDM
34 {
35 
36 /**
37 Array of two short integers
38 Value Syntax 	short short
39 Value Meaning 	value1 value2
40 Example 		setAttr node.short2Attr -type short2 1 2;
41 */
42 struct short2
43 {
44 	short values[2];
short2short245 	short2(short s1, short s2)
46 	{
47 		values[0] = s1;
48 		values[1] = s2;
49 	}
50 	short operator[](size_t i) const
51 	{
52 		MAYADM_ASSERT( i < 2 );
53 		return values[i];
54 	}
55 	short& operator[](size_t i)
56 	{
57 		MAYADM_ASSERT( i < 2 );
58 		return values[i];
59 	}
writeshort260 	void write(FILE* file) const
61 	{
62 		fprintf(file, "%i %i", values[0], values[1]);
63 	}
64 };
65 
66 inline bool operator==(const short2& d1, const short2& d2)
67 {
68 	if(d1[0] != d2[0])
69 		return false;
70 	if(d1[1] != d2[1])
71 		return false;
72 	return true;
73 }
74 
75 /**
76 Array of three short integers
77 Value Syntax 	short short short
78 Value Meaning 	value1 value2 value3
79 Example 		setAttr node.short3Attr -type short3 1 2 3;
80 */
81 struct short3
82 {
83 	short values[3];
84 	short operator[](size_t i) const
85 	{
86 		MAYADM_ASSERT( i < 3 );
87 		return values[i];
88 	}
89 	short& operator[](size_t i)
90 	{
91 		MAYADM_ASSERT( i < 3 );
92 		return values[i];
93 	}
writeshort394 	void write(FILE* file) const
95 	{
96 		fprintf(file, "%i %i %i", values[0], values[1], values[2]);
97 	}
98 };
99 
100 inline bool operator==(const short3& d1, const short3& d2)
101 {
102 	if(d1[0] != d2[0])
103 		return false;
104 	if(d1[1] != d2[1])
105 		return false;
106 	if(d1[2] != d2[2])
107 		return false;
108 	return true;
109 }
110 
111 /**
112 Array of two long integers
113 Value Syntax 	long long
114 Value Meaning 	value1 value2
115 Example 		setAttr node.long2Attr -type long2 1000000 2000000;
116 */
117 struct long2
118 {
119 	int values[2];
long2long2120 	long2(int l1, int l2)
121 	{
122 		 values[0]=l1;
123 		 values[1]=l2;
124 	}
125 	int operator[](size_t i) const
126 	{
127 		MAYADM_ASSERT( i < 2 );
128 		return values[i];
129 	}
130 	int& operator[](size_t i)
131 	{
132 		MAYADM_ASSERT( i < 2 );
133 		return values[i];
134 	}
writelong2135 	void write(FILE* file) const
136 	{
137 		fprintf(file, "%i %i", values[0], values[1]);
138 	}
139 };
140 
141 inline bool operator==(const long2& d1, const long2& d2)
142 {
143 	if(d1[0] != d2[0])
144 		return false;
145 	if(d1[1] != d2[1])
146 		return false;
147 	return true;
148 }
149 
150 /**
151 Array of three long integers
152 Value Syntax 	long long long
153 Value Meaning 	value1 value2 value3
154 Example		 	setAttr node.long3Attr -type long3 1000000 2000000 3000000;
155 */
156 struct long3
157 {
158 	int values[3];
long3long3159 	long3(int v1,int v2,int v3)
160 	{
161 		values[0]=v1;
162 		values[1]=v2;
163 		values[2]=v3;
164 	}
165 	int operator[](size_t i) const
166 	{
167 		MAYADM_ASSERT( i < 3 );
168 		return values[i];
169 	}
170 	int& operator[](size_t i)
171 	{
172 		MAYADM_ASSERT( i < 3 );
173 		return values[i];
174 	}
writelong3175 	void write(FILE* file) const
176 	{
177 		fprintf(file, "%i %i %i", values[0], values[1], values[2]);
178 	}
179 };
180 
181 inline bool operator==(const long3& d1, const long3& d2)
182 {
183 	if(d1[0] != d2[0])
184 		return false;
185 	if(d1[1] != d2[1])
186 		return false;
187 	if(d1[2] != d2[2])
188 		return false;
189 	return true;
190 }
191 
192 /**
193 Variable length array of long integers
194 */
195 struct int32Array
196 {
197 	size_t size;
198 	int* values;
199 
int32Arrayint32Array200 	int32Array(size_t s):size(s), values(new int[s]){}
~int32Arrayint32Array201 	~int32Array(){delete [] values;}
202 
203 	int operator[](size_t i) const
204 	{
205 		MAYADM_ASSERT( i < size );
206 		return values[i];
207 	}
208 	int& operator[](size_t i)
209 	{
210 		MAYADM_ASSERT( i < size );
211 		return values[i];
212 	}
writeint32Array213 	void write(FILE* file) const
214 	{
215 		for(size_t i=0; i<size; ++i)
216 		{
217 			fprintf(file, "%i", values[i]);
218 			if(i+1<size) fprintf(file, " ");
219 		}
220 	}
221 };
222 
223 typedef int32Array intArray;
224 
225 /**
226 Array of two floats
227 Value Syntax 	float float
228 Value Meaning 	value1 value2
229 Example 		setAttr node.float2Attr -type float2 1.1 2.2;
230 */
231 struct float2
232 {
233 	float values[2];
float2float2234 	float2(float v1, float v2)
235 	{
236 		values[0] = v1;
237 		values[1] = v2;
238 	}
239 	float operator[](size_t i) const
240 	{
241 		MAYADM_ASSERT( i < 2 );
242 		return values[i];
243 	}
244 	float& operator[](size_t i)
245 	{
246 		MAYADM_ASSERT( i < 2 );
247 		return values[i];
248 	}
writefloat2249 	void write(FILE* file) const
250 	{
251 		fprintf(file, "%f %f", values[0], values[1]);
252 	}
253 };
254 
255 inline bool operator==(const float2& d1, const float2& d2)
256 {
257 	if(d1[0] != d2[0])
258 		return false;
259 	if(d1[1] != d2[1])
260 		return false;
261 	return true;
262 }
263 
264 /**
265 Array of three floats
266 Value Syntax 	float float float
267 Value Meaning 	value1 value2 value3
268 Example 		setAttr node.float3Attr -type float3 1.1 2.2 3.3;
269 */
270 struct float3
271 {
272 	float values[3];
float3float3273 	float3(float v1,float v2,float v3)
274 	{
275 		values[0]=v1;
276 		values[1]=v2;
277 		values[2]=v3;
278 	}
279 	float operator[](size_t i) const
280 	{
281 		MAYADM_ASSERT( i < 3 );
282 		return values[i];
283 	}
284 	float& operator[](size_t i)
285 	{
286 		MAYADM_ASSERT( i < 3 );
287 		return values[i];
288 	}
writefloat3289 	void write(FILE* file) const
290 	{
291 		fprintf(file, "%f %f %f", values[0], values[1], values[2]);
292 	}
293 };
294 
295 inline bool operator==(const float3& d1, const float3& d2)
296 {
297 	if(d1[0] != d2[0])
298 		return false;
299 	if(d1[1] != d2[1])
300 		return false;
301 	if(d1[2] != d2[2])
302 		return false;
303 	return true;
304 }
305 
306 /**
307 Array of two doubles
308 Value Syntax 	double double
309 Value Meaning 	value1 value2
310 Example 		setAttr node.double2Attr -type double2 1.1 2.2;
311 */
312 struct double2
313 {
314 	double values[2];
double2double2315 	double2( double d1, double d2)
316 	{
317 		values[0]=d1;
318 		values[1]=d2;
319 	}
320 	double operator[](size_t i) const
321 	{
322 		MAYADM_ASSERT( i < 2 );
323 		return values[i];
324 	}
325 	double& operator[](size_t i)
326 	{
327 		MAYADM_ASSERT( i < 2 );
328 		return values[i];
329 	}
writedouble2330 	void write(FILE* file) const
331 	{
332 		fprintf(file, "%f %f", values[0], values[1]);
333 	}
334 };
335 
336 inline bool operator==(const double2& d1, const double2& d2)
337 {
338 	if(d1[0] != d2[0])
339 		return false;
340 	if(d1[1] != d2[1])
341 		return false;
342 	return true;
343 }
344 
345 /**
346 Array of three doubles
347 Value Syntax 	double double double
348 Value Meaning 	value1 value2 value3
349 Example 		setAttr node.double3Attr -type double3 1.1 2.2 3.3;
350 */
351 struct double3
352 {
353 	double values[3];
double3double3354 	double3(double val1, double val2, double val3)
355 	{
356 		values[0] = val1;
357 		values[1] = val2;
358 		values[2] = val3;
359 	}
360 	double operator[](size_t i) const
361 	{
362 		MAYADM_ASSERT( i < 3 );
363 		return values[i];
364 	}
365 	double& operator[](size_t i)
366 	{
367 		MAYADM_ASSERT( i < 3 );
368 		return values[i];
369 	}
writedouble3370 	void write(FILE* file) const
371 	{
372 		fprintf(file,"%f %f %f", values[0], values[1], values[2]);
373 	}
374 };
375 
376 inline bool operator==(const double3& d1, const double3& d2)
377 {
378 	if(d1[0] != d2[0])
379 		return false;
380 	if(d1[1] != d2[1])
381 		return false;
382 	if(d1[2] != d2[2])
383 		return false;
384 	return true;
385 }
386 inline bool operator==(const double3& d1, double d)
387 {
388 	if(d1[0] != d)
389 		return false;
390 	if(d1[1] != d)
391 		return false;
392 	if(d1[2] != d)
393 		return false;
394 	return true;
395 }
396 
397 /**
398 Array of three doubles
399 Value Syntax 	double double double
400 Value Meaning 	value1 value2 value3
401 Example 		setAttr node.double3Attr -type double3 1.1 2.2 3.3;
402 */
403 struct double4
404 {
405 	double values[4];
406 	double operator[](size_t i) const
407 	{
408 		MAYADM_ASSERT( i < 4 );
409 		return values[i];
410 	}
411 	double& operator[](size_t i)
412 	{
413 		MAYADM_ASSERT( i < 4 );
414 		return values[i];
415 	}
writedouble4416 	void write(FILE* file) const
417 	{
418 		fprintf(file,"%f %f %f %f", values[0], values[1], values[2], values[3]);
419 	}
420 };
421 
422 inline bool operator==(const double4& d1, const double4& d2)
423 {
424 	if(d1[0] != d2[0])
425 		return false;
426 	if(d1[1] != d2[1])
427 		return false;
428 	if(d1[2] != d2[2])
429 		return false;
430 	if(d1[3] != d2[3])
431 		return false;
432 	return true;
433 }
434 
435 /**
436 Variable length array of doubles
437 Value Syntax 	int {double}
438 Value Meaning 	numberOfArrayValues {arrayValue}
439 Example 		setAttr node.doubleArrayAttr -type doubleArray 2 3.14159 2.782;
440 */
441 struct doubleArray
442 {
443 	size_t size;
444 	double* values;
445 
doubleArraydoubleArray446 	doubleArray(size_t s):size(s), values(new double[s]){}
~doubleArraydoubleArray447 	~doubleArray(){delete [] values;}
448 
449 	double operator[](size_t i) const
450 	{
451 		MAYADM_ASSERT( i < size );
452 		return values[i];
453 	}
454 	double& operator[](size_t i)
455 	{
456 		MAYADM_ASSERT( i < size );
457 		return values[i];
458 	}
writedoubleArray459 	void write(FILE* file) const
460 	{
461 		for(size_t i=0; i<size; ++i)
462 		{
463 			fprintf(file,"%f", values[i]);
464 			if(i+1<size) fprintf(file," ");
465 		}
466 	}
467 };
468 
469 /**
470 4x4 matrix of doubles
471 
472 Value Syntax
473 	double double double double
474 	double double double double
475 	double double double double
476 	double double double double
477 
478 Value Meaning
479 	row1col1 row1col2 row1col3 row1col4
480 	row2col1 row2col2 row2col3 row2col4
481 	row3col1 row3col2 row3col3 row3col4
482 	row4col1 row4col2 row4col3 row4col4
483 
484 Alternate Syntax
485 	string double double double
486 	double double double
487 	integer
488 	double double double
489 	double double double
490 	double double double
491 	double double double
492 	double double double
493 	double double double
494 	double double double double
495 	double double double double
496 	double double double
497 	boolean
498 
499 Alternate Meaning
500 	"xform" scaleX scaleY scaleZ
501 	rotateX rotateY rotateZ
502 	rotationOrder (0=XYZ, 1=YZX, 2=ZXY, 3=XZY, 4=YXZ, 5=ZYX)
503 	translateX translateY translateZ
504 	shearXY shearXZ shearYZ
505 	scalePivotX scalePivotY scalePivotZ
506 	scaleTranslationX scaleTranslationY scaleTranslationZ
507 	rotatePivotX rotatePivotY rotatePivotZ
508 	rotateTranslationX rotateTranslationY rotateTranslationZ
509 	rotateOrientW rotateOrientX rotateOrientY rotateOrientZ
510 	jointOrientW jointOrientX jointOrientY jointOrientZ
511 	inverseParentScaleX inverseParentScaleY inverseParentScaleZ
512 	compensateForParentScale
513 
514 Example
515 	setAttr node.matrixAttr -type "matrix" 1 0 0 0 0 1 0 0 0 0 1 0 2 3 4 1;
516 	setAttr node.matrixAttr -type "matrix" "xform" 1 1 1 0 0 0 0 2 3 4 0 0 0
517 		0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 0 false;
518 */
519 struct matrix
520 {
521     double m[4][4];
matrixmatrix522     matrix(double mtx[4][4])
523     {
524         setAllElements (
525             mtx[0][0],mtx[0][1],mtx[0][2],mtx[0][3],
526             mtx[1][0],mtx[1][1],mtx[1][2],mtx[1][3],
527             mtx[2][0],mtx[2][1],mtx[2][2],mtx[2][3],
528             mtx[3][0],mtx[3][1],mtx[3][2],mtx[3][3] );
529     }
530 
matrixmatrix531     matrix(
532         double m00, double m01, double m02, double m03,
533         double m10, double m11, double m12, double m13,
534         double m20, double m21, double m22, double m23,
535         double m30, double m31, double m32, double m33 )
536     {
537         setAllElements(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33);
538     }
539 
setAllElementsmatrix540     void setAllElements (
541         double m00, double m01, double m02, double m03,
542         double m10, double m11, double m12, double m13,
543         double m20, double m21, double m22, double m23,
544         double m30, double m31, double m32, double m33 )
545     {
546         m[0][0] = m00;
547         m[0][1] = m01;
548         m[0][2] = m02;
549         m[0][3] = m03;
550 
551         m[1][0] = m10;
552         m[1][1] = m11;
553         m[1][2] = m12;
554         m[1][3] = m13;
555 
556         m[2][0] = m20;
557         m[2][1] = m21;
558         m[2][2] = m22;
559         m[2][3] = m23;
560 
561         m[3][0] = m30;
562         m[3][1] = m31;
563         m[3][2] = m32;
564         m[3][3] = m33;
565     }
566 
567 	// member access, allows use of construct mat[r][c]
568 	inline double* operator[] ( size_t iRow ) const
569 	{
570 		MAYADM_ASSERT(iRow < 4);
571 		return ( double* ) m[ iRow ];
572 	}
573 
writematrix574 	void write(FILE* file) const
575 	{
576 		fprintf(file,"%f %f %f %f ", m[0][0], m[0][1], m[0][2], m[0][3]);
577 		fprintf(file,"%f %f %f %f ", m[1][0], m[1][1], m[1][2], m[1][3]);
578 		fprintf(file,"%f %f %f %f ", m[2][0], m[2][1], m[2][2], m[2][3]);
579 		fprintf(file,"%f %f %f %f", m[3][0], m[3][1], m[3][2], m[3][3]);
580 	}
581 };
582 
583 const matrix identity(1,0,0,0,
584 					  0,1,0,0,
585 					  0,0,1,0,
586 					  0,0,0,1);
587 
588 inline bool operator==(const matrix& m1, const matrix& m2)
589 {
590 	for(size_t r=0; r<4; ++r)
591 	{
592 		for(size_t c=0; c<4; ++c)
593 		{
594 			if(m1[r][c] != m2[r][c])
595 				return false;
596 		}
597 	}
598 	return true;
599 }
600 
601 /**
602 Variable length array of points
603 Value Syntax 	int {double double double double}
604 Value Meaning 	numberOfArrayValues {xValue yValue zValue wValue}
605 Example 		setAttr node.pointArrayAttr -type pointArray 2 1 1 1 1 2 2 2 1;
606 */
607 struct point
608 {
609 	double x;
610 	double y;
611 	double z;
612 	double w;
writepoint613 	void write(FILE* file) const
614 	{
615 		fprintf(file,"%f %f %f %f", x, y, z, w);
616 	}
617 };
618 struct pointArray
619 {
620 	size_t size;
621 	point* values;
pointArraypointArray622 	pointArray(size_t s):size(s), values(new point[s]){}
~pointArraypointArray623 	~pointArray(){delete [] values;}
624 	point operator[](size_t i) const
625 	{
626 		MAYADM_ASSERT( i < size );
627 		return values[i];
628 	}
629 	point& operator[](size_t i)
630 	{
631 		MAYADM_ASSERT( i < size );
632 		return values[i];
633 	}
writepointArray634 	void write(FILE* file) const
635 	{
636 		for(size_t i=0; i<size; ++i)
637 		{
638 			values[i].write(file);
639 			if(i+1<size) fprintf(file," ");
640 		}
641 	}
642 };
643 
644 /**
645 Variable length array of vectors
646 Value Syntax 	int {double double double}
647 Value Meaning 	numberOfArrayValues {xValue yValue zValue}
648 Example 		setAttr node.vectorArrayAttr -type vectorArray 2 1 1 1 2 2 2;
649 */
650 struct vector
651 {
652 	double x;
653 	double y;
654 	double z;
writevector655 	void write(FILE* file) const
656 	{
657 		fprintf(file,"%f %f %f", x, y, z);
658 	}
659 };
660 struct vectorArray
661 {
662 	size_t size;
663 	vector* values;
vectorArrayvectorArray664 	vectorArray(size_t s):size(s), values(new vector[s]){}
~vectorArrayvectorArray665 	~vectorArray(){delete [] values;}
666 	vector operator[](size_t i) const
667 	{
668 		MAYADM_ASSERT( i < size );
669 		return values[i];
670 	}
671 	vector& operator[](size_t i)
672 	{
673 		MAYADM_ASSERT( i < size );
674 		return values[i];
675 	}
writevectorArray676 	void write(FILE* file) const
677 	{
678 		for(size_t i=0; i<size; ++i)
679 		{
680 			values[i].write(file);
681 			if(i+1<size) fprintf(file," ");
682 		}
683 	}
684 };
685 
686 /**
687 Character string
688 Value Syntax 	string
689 Value Meaning 	characterStringValue
690 Example 		setAttr node.stringAttr -type "string" "blarg";
691 */
692 struct string
693 {
694 	std::string str;
stringstring695 	string(){}
stringstring696 	string(const char* cstr): str(cstr){}
stringstring697 	string(const std::string& s): str(s){}
698 
699 	string& operator=(const char* cstr)
700 	{
701 		str = cstr;
702 		return *this;
703 	}
704 	string& operator=(const std::string& s)
705 	{
706 		str = s;
707 		return *this;
708 	}
c_strstring709 	const char* c_str()
710 	{
711 		return str.c_str();
712 	}
writestring713 	void write(FILE* file) const
714 	{
715 		fprintf(file, "\"%s\"", str.c_str());
716 	}
717 };
718 
719 inline bool operator==(const string& s1, const string& s2)
720 {
721 	return s1.str == s2.str;
722 }
723 
724 /**
725 Variable length array of strings
726 Value Syntax 	int {string}
727 Value Meaning 	numberOfArrayValues {arrayValue}
728 Example 		setAttr node.stringArrayAttr -type stringArray 3 "a" "b" "c";
729 */
730 struct stringArray
731 {
732 	size_t size;
733 	string* values;
stringArraystringArray734 	stringArray(size_t s):size(s), values(new string[s]){}
~stringArraystringArray735 	~stringArray(){delete [] values;}
736 	string operator[](size_t i) const
737 	{
738 		MAYADM_ASSERT( i < size );
739 		return values[i];
740 	}
741 	string& operator[](size_t i)
742 	{
743 		MAYADM_ASSERT( i < size );
744 		return values[i];
745 	}
writestringArray746 	void write(FILE* file) const
747 	{
748 		for(size_t i=0; i<size; ++i)
749 		{
750 			values[i].write(file);
751 			if(i+1<size) fprintf(file," ");
752 		}
753 	}
754 };
755 
756 /**
757 Sphere data
758 Value Syntax 	double
759 Value Meaning 	sphereRadius
760 Example 		setAttr node.sphereAttr -type sphere 5.0;
761 */
762 struct sphere
763 {
764 	double radius;
writesphere765 	void write(FILE* file) const
766 	{
767 		fprintf(file,"%f", radius);
768 	}
769 };
770 
771 /**
772 Cone data
773 Value Syntax 	double double
774 Value Meaning 	coneAngle coneCap
775 Example 		setAttr node.coneAttr -type cone 45.0 5.0;
776 */
777 struct cone
778 {
779 	double coneAngle;
780 	double coneCap;
writecone781 	void write(FILE* file) const
782 	{
783 		fprintf(file, "%f %f", coneAngle, coneCap);
784 	}
785 };
786 
787 /**
788 Reflectance data
789 Value Syntax 	double double double
790 Value Meaning 	redReflect greenReflect blueReflect
791 Example 		setAttr node.reflectanceRGBAttr -type reflectanceRGB 0.5 0.5 0.1;
792 */
793 struct reflectanceRGB
794 {
795 	double redReflect;
796 	double greenReflect;
797 	double blueReflect;
writereflectanceRGB798 	void write(FILE* file) const
799 	{
800 		fprintf(file, "%f %f %f", redReflect, greenReflect, blueReflect);
801 	}
802 };
803 
804 /**
805 Spectrum data
806 Value Syntax 	double double double
807 Value Meaning 	redSpectrum greenSpectrum blueSpectrum
808 Example 		setAttr node.spectrumRGBAttr -type spectrumRGB 0.5 0.5 0.1;
809 */
810 struct spectrumRGB
811 {
812 	double redSpectrum;
813 	double greenSpectrum;
814 	double blueSpectrum;
writespectrumRGB815 	void write(FILE* file) const
816 	{
817 		fprintf(file, "%f %f %f", redSpectrum, greenSpectrum, blueSpectrum);
818 	}
819 };
820 
821 /**
822 Variable length array of components
823 Value Syntax 	int {string}
824 Value Meaning 	numberOfComponents {componentName}
825 Example 		setAttr node.componentListAttr -type componentList 3 cv[1] cv[12] cv[3];
826 */
827 class componentList : public std::vector<string>
828 {
829 public:
componentList()830 	componentList(){}
componentList(size_t s)831 	componentList(size_t s):std::vector<string>(s){}
~componentList()832 	~componentList(){}
write(FILE * file)833 	void write(FILE* file) const
834 	{
835 		fprintf(file,"%i ", size());
836 		for(size_t i=0; i<size(); ++i)
837 		{
838 			at(i).write(file);
839 			if(i+1<size()) fprintf(file," ");
840 		}
841 	}
842 };
843 
844 /**
845 NURBS curve data
846 Value Syntax
847 	int int int bool int int {double}
848 	int {double double double}
849 Value Meaning
850 	degree spans form isRational dimension knotCount {knotValue}
851 	cvCount {xCVValue yCVValue [zCVValue] [wCVValue]}
852 
853 Example
854 	setAttr node.curveAttr -type nurbsCurve 3 1 0 no 3
855 		6 0 0 0 1 1 1
856 		4 -2 3 0 -2 1 0 -2 -1 0 -2 -3 0;
857 */
858 struct nurbsCurve
859 {
860 	/** degree is the degree of the curve(range 1-7) */
861 	int degree;
862 	/** spans is the number of spans*/
863 	int spans;
864 	/** form is open (0), closed (1), periodic (2)*/
865 	int form;
866 	/** isRational is true if the curve CVs contain a rational component*/
867 	bool isRational;
868 	/**  dimension is 2 or 3, depending on the dimension of the curve*/
869 	int dimension;
870 	/** knotCount is the size of the knot list*/
871 	int knotCount;
872 	/** knotValue is a single entry in the knot list*/
873 	double* knotValues;
874 	/** cvCount is the number of CVs in the curve*/
875 	int cvCount;
876 	/**
877 	xCVValue,yCVValue,[zCVValue] [wCVValue] is a single CV.
878 	zCVValue is only present when dimension is 3.
879 	wCVValue is only present when isRational is true.
880 	*/
881 	double* cvValues;
882 
nurbsCurvenurbsCurve883 	nurbsCurve()
884 	{
885 		degree=0;
886 		spans=0;
887 		form=0;
888 		isRational=false;
889 		dimension=0;
890 		knotCount=0;
891 		knotValues=0;
892 		cvCount=0;
893 		cvValues=0;
894 	}
~nurbsCurvenurbsCurve895 	~nurbsCurve()
896 	{
897 		delete [] knotValues;
898 		delete [] cvValues;
899 	}
900 
writenurbsCurve901 	void write(FILE* file) const
902 	{
903 		fprintf(file,"%i %i %i %i %i %i ", degree, spans, form, isRational, dimension, knotCount);
904 		for(int i=0; i<knotCount; ++i)
905 		{
906 			fprintf(file, "%f ", knotValues[i]);
907 		}
908 		fprintf(file, "%i ", cvCount);
909 		size_t numElements = 2;
910 		if(dimension == 3) numElements++;
911 		if(isRational) 	numElements++;
912 		size_t size = cvCount * numElements;
913 		for(size_t i=0; i<size; ++i)
914 		{
915 			fprintf(file, "%f", cvValues[i]);
916 			if(i+1<size) fprintf(file," ");
917 		}
918 	}
919 };
920 
921 /**
922 NURBS surface data
923 Value Syntax
924 	int int int int bool
925 	int {double}
926 	int {double}
927 	[string] int {double double double}
928 Value Meaning
929 	uDegree vDegree uForm vForm isRational
930 	uKnotCount {uKnotValue}
931 	vKnotCount {vKnotValue}
932 	["TRIM"|"NOTRIM"] cvCount {xCVValue yCVValue zCVValue [wCVValue]}
933 Example
934 	setAttr node.surfaceAttr -type nurbsSurface 3 3 0 0 no
935 		6 0 0 0 1 1 1
936 		6 0 0 0 1 1 1
937 		16 -2 3 0 -2 1 0 -2 -1 0 -2 -3 0
938 		-1 3 0 -1 1 0 -1 -1 0 -1 -3 0
939 		1 3 0 1 1 0 1 -1 0 1 -3 0
940 		3 3 0 3 1 0 3 -1 0 3 -3 0;
941 */
942 struct nurbsSurface
943 {
944 	enum trimOpt {TRIM, NOTRIM};
945 	/** uDegree is degree of the surface in U direction (range 1-7)*/
946 	int uDegree;
947 	/** vDegree is degree of the surface in V direction (range 1-7)*/
948 	int vDegree;
949 	/** uForm is open (0), closed (1), periodic (2) in U direction*/
950 	int uForm;
951 	/** vForm is open (0), closed (1), periodic (2) in V direction*/
952 	int vForm;
953 	/** isRational is true if the surface CVs contain a rational component*/
954 	bool isRational;
955 	/** uKnotCount is the size of the U knot list*/
956 	int	uKnotCount;
957 	/** uKnotValue is a single entry in the U knot list*/
958 	double* uKnotValues;
959 	/** vKnotCount is the size of the V knot list*/
960 	int vKnotCount;
961 	/** vKnotValue is a single entry in the V knot list*/
962 	double* vKnotValues;
963 	/** If "TRIM" is specified then additional trim information is expected
964 	If "NOTRIM" is specified then the surface is not trimmed*/
965 	trimOpt trim;
966 	/** cvCount is the number of CVs in the surface*/
967 	int cvCount;
968 	/**
969 	xCVValue,yCVValue,zCVValue [wCVValue]is a single CV.
970 	zCVValue is only present when dimension is 3.
971 	wCVValue is only present when isRational is true
972 	*/
973 	double* cvValues;
974 
nurbsSurfacenurbsSurface975 	nurbsSurface()
976 	{
977 		uKnotValues = 0;
978 		vKnotValues = 0;
979 		cvValues = 0;
980 	}
~nurbsSurfacenurbsSurface981 	~nurbsSurface()
982 	{
983 		delete [] uKnotValues;
984 		delete [] vKnotValues;
985 		delete [] cvValues;
986 	}
987 
writenurbsSurface988 	void write(FILE* file) const
989 	{
990 		fprintf(file,"%i %i %i %i %i %i ", uDegree, vDegree, uForm, vForm, isRational, uKnotCount);
991 		for(int i=0; i<uKnotCount; ++i)
992 		{
993 			fprintf(file, "%f ", uKnotValues[i]);
994 		}
995 		fprintf(file,"%i ", vKnotCount);
996 		for(int i=0; i<uKnotCount; ++i)
997 		{
998 			fprintf(file, "%f ", uKnotValues[i]);
999 		}
1000 		if(trim == TRIM){
1001 			fprintf(file, "\"%s\" ", "TRIM");
1002 		} else
1003 		{
1004 			fprintf(file, "\"%s\" ", "NOTRIM");
1005 		}
1006 		fprintf(file, "%i ", cvCount);
1007 		size_t numElements = 3;
1008 		if(isRational) 	numElements++;
1009 		size_t size = cvCount * numElements;
1010 		for(size_t i=0; i<size; ++i)
1011 		{
1012 			fprintf(file, "%f", cvValues[i]);
1013 			if(i+1<size) fprintf(file," ");
1014 		}
1015 	}
1016 };
1017 /**
1018 NURBS trim face data
1019 
1020 Value Syntax
1021 	bool int {int {int {int int int} int {int int}}}
1022 Value Meaning
1023 	flipNormal boundaryCount {boundaryType tedgeCountOnBoundary
1024 	{splineCountOnEdge {edgeTolerance isEdgeReversed geometricContinuity}
1025 	{splineCountOnPedge {isMonotone pedgeTolerance}}}
1026 */
1027 struct nurbsTrimface
1028 {
1029 	/** flipNormal if true turns the surface inside out*/
1030 	bool flipNormal;
1031 	/** boundaryCount: number of boundaries*/
1032 	int boundaryCount;
1033 
1034 	struct boundary {
1035 		int boundaryType;
1036 		/** tedgeCountOnBoundary : number of edges in a boundary*/
1037 		int tedgeCountOnBoundary;
1038 		struct edge {
1039 			/** splineCountOnEdge : number of splines in an edge in*/
1040 			int splineCountOnEdge;
1041 			struct splineOnEdge {
1042 				/** edgeTolerance : tolerance used to build the 3d edge*/
1043 				int edgeTolerance;
1044 				/** isEdgeReversed : if true, the edge is backwards*/
1045 				int isEdgeReversed;
1046 				/** geometricContinuity : if true, the edge is tangent continuous*/
1047 				int geometricContinuity;
1048 
writenurbsTrimface::boundary::edge::splineOnEdge1049 				void write(FILE* file) const
1050 				{
1051 					fprintf(file, "%i %i %i", edgeTolerance, isEdgeReversed, geometricContinuity);
1052 				}
1053 			} *splinesOnEdge;
1054 
1055 			/** splineCountOnPedge : number of splines in a 2d edge*/
1056 			int	splineCountOnPedge;
1057 			struct splineOnPedge {
1058 				/** isMonotone : if true, curvature is monotone*/
1059 				int isMonotone;
1060 				/** pedgeTolerance : tolerance for the 2d edge*/
1061 				int	pedgeTolerance;
1062 
writenurbsTrimface::boundary::edge::splineOnPedge1063 				void write(FILE* file) const
1064 				{
1065 					fprintf(file, "%i %i", isMonotone, pedgeTolerance);
1066 				}
1067 			} *splinesOnPedge;
1068 
edgenurbsTrimface::boundary::edge1069 			edge()
1070 			{
1071 				splinesOnEdge = 0;
1072 				splinesOnPedge = 0;
1073 			}
~edgenurbsTrimface::boundary::edge1074 			~edge()
1075 			{
1076 				delete [] splinesOnEdge;
1077 				delete [] splinesOnPedge;
1078 			}
1079 
writenurbsTrimface::boundary::edge1080 			void write(FILE* file) const
1081 			{
1082 				fprintf(file,"%i ", splineCountOnEdge);
1083 				for(int i=0; i<splineCountOnEdge; ++i)
1084 				{
1085 					splinesOnEdge[i].write(file);
1086 					if(i+1<splineCountOnEdge) fprintf(file, " ");
1087 				}
1088 				fprintf(file,"%i ", splineCountOnPedge);
1089 				for(int i=0; i<splineCountOnPedge; ++i)
1090 				{
1091 					splinesOnPedge[i].write(file);
1092 					if(i+1<splineCountOnPedge) fprintf(file, " ");
1093 				}
1094 			}
1095 		} *edges;
1096 
boundarynurbsTrimface::boundary1097 		boundary()
1098 		{
1099 			edges = 0;
1100 		}
~boundarynurbsTrimface::boundary1101 		~boundary()
1102 		{
1103 			delete [] edges;
1104 		}
1105 
writenurbsTrimface::boundary1106 		void write(FILE* file) const
1107 		{
1108 			fprintf(file,"%i %i ", boundaryType, tedgeCountOnBoundary);
1109 			for(int i=0; i<tedgeCountOnBoundary; ++i)
1110 			{
1111 				edges[i].write(file);
1112 				if(i+1<tedgeCountOnBoundary) fprintf(file, " ");
1113 			}
1114 		}
1115 	} *boundaries;
1116 
nurbsTrimfacenurbsTrimface1117 	nurbsTrimface()
1118 	{
1119 		boundaries = 0;
1120 	}
~nurbsTrimfacenurbsTrimface1121 	~nurbsTrimface()
1122 	{
1123 		delete [] boundaries;
1124 	}
1125 
writenurbsTrimface1126 	void write(FILE* file) const
1127 	{
1128 		fprintf(file,"%i %i ", flipNormal, boundaryCount);
1129 		for(int i=0; i<boundaryCount; ++i)
1130 		{
1131 			boundaries[i].write(file);
1132 			if(i+1<boundaryCount) fprintf(file, " ");
1133 		}
1134 	}
1135 };
1136 
1137 /**
1138 Polygon face data
1139 
1140 This data type (polyFace) is meant to be used in file I/O
1141 after setAttrs have been written out for vertex position
1142 arrays, edge connectivity arrays (with corresponding start
1143 and end vertex descriptions), texture coordinate arrays and
1144 color arrays. The reason is that this data type references
1145 all of its data through ids created by the former types.
1146 
1147 Value Syntax
1148 	{"f" int {int}}
1149 	{"h" int {int}}
1150 	{"mf" int {int}}
1151 	{"mh" int {int}}
1152 	{"mu" int int {int}}
1153     {"mc" int int {int}}
1154 	{"fc" int {int}}
1155 
1156 Value Meaning
1157 	{f faceEdgeCount {edgeIdValue}}
1158 	{h holeEdgeCount {edgeIdValue}}
1159 	{mf faceUVCount {uvIdValue}}
1160 	{mh holeUVCount {uvIdValue}}
1161 	{mu uvSet faceUVCount {uvIdValue}}
1162     {mc color faceUVCount {colorIdValue}}
1163 	{fc faceColorCount {colorIndexValue}}
1164 
1165 Example:
1166 	setAttr node.polyFaceAttr -type polyFaces f 3 1 2 3 fc 3 4 4 6;
1167 */
1168 struct polyFaces
1169 {
1170 	/**
1171 	"f" specifies the ids of the edges making up a face -
1172 	negative value if the edge is reversed in the face
1173 
1174 	Format: {f faceEdgeCount {edgeIdValue}}
1175 	*/
1176 	struct F{
1177 		int faceEdgeCount;
1178 		int* edgeIdValue;
1179 
FpolyFaces::F1180 		F()
1181 		{
1182 			faceEdgeCount = 0;;
1183 			edgeIdValue= 0;
1184 		}
~FpolyFaces::F1185 		~F()
1186 		{
1187 			faceEdgeCount = 0;;
1188 			delete [] edgeIdValue;
1189 		}
1190 
writepolyFaces::F1191 		void write(FILE* file) const
1192 		{
1193 			fprintf(file,"\t\tf %i ", faceEdgeCount);
1194 			for(int i=0; i<faceEdgeCount; ++i)
1195 			{
1196 				fprintf(file,"%i", edgeIdValue[i]);
1197 				if(i+1<faceEdgeCount) fprintf(file, " ");
1198 			}
1199 		}
1200 	}f;
1201 
1202 	/**
1203 	"h" specifies the ids of the edges making up a hole -
1204 	negative value if the edge is reversed in the face
1205 
1206 	Format: {h holeEdgeCount {edgeIdValue}}
1207 	*/
1208 	struct H{
1209 		int holeEdgeCount;
1210 		int* edgeIdValue;
1211 
HpolyFaces::H1212 		H()
1213 		{
1214 			holeEdgeCount=0;
1215 			edgeIdValue=0;
1216 		}
~HpolyFaces::H1217 		~H()
1218 		{
1219 			holeEdgeCount=0;
1220 			delete [] edgeIdValue;
1221 		}
1222 
writepolyFaces::H1223 		void write(FILE* file) const
1224 		{
1225 			fprintf(file,"\t\th %i ", holeEdgeCount);
1226 			for(int i=0; i<holeEdgeCount; ++i)
1227 			{
1228 				fprintf(file,"%i", edgeIdValue[i]);
1229 				if(i+1<holeEdgeCount) fprintf(file, " ");
1230 			}
1231 		}
1232 	}h;
1233 
1234 	/**
1235 	"mf" specifies the ids of texture coordinates (uvs) for a face.
1236 	This data type is obsolete as of version 3.0. It is replaced by "mu".
1237 
1238 	Format: {mf faceUVCount {uvIdValue}}
1239 	*/
1240 	struct MF{
1241 		int faceUVCount;
1242 		int* uvIdValue;
1243 
MFpolyFaces::MF1244 		MF()
1245 		{
1246 			faceUVCount=0;
1247 			uvIdValue=0;
1248 		}
~MFpolyFaces::MF1249 		~MF()
1250 		{
1251 			faceUVCount=0;
1252 			delete [] uvIdValue;
1253 		}
1254 
writepolyFaces::MF1255 		void write(FILE* file) const
1256 		{
1257 			fprintf(file,"\t\tmf %i ", faceUVCount);
1258 			for(int i=0; i<faceUVCount; ++i)
1259 			{
1260 				fprintf(file,"%i", uvIdValue[i]);
1261 				if(i+1<faceUVCount) fprintf(file, " ");
1262 			}
1263 		}
1264 	}mf;
1265 
1266 
1267 	/**
1268 	"mh" specifies the ids of texture coordinates (uvs) for a hole
1269 	This data type is obsolete as of version 3.0. It is replaced by "mu".
1270 
1271 	Format: {mh holeUVCount {uvIdValue}}
1272 	*/
1273 	struct MH{
1274 		int holeUVCount;
1275 		int* uvIdValue;
1276 
MHpolyFaces::MH1277 		MH()
1278 		{
1279 			holeUVCount=0;
1280 			uvIdValue=0;
1281 		}
~MHpolyFaces::MH1282 		~MH()
1283 		{
1284 			holeUVCount=0;
1285 			delete [] uvIdValue;
1286 		}
writepolyFaces::MH1287 		void write(FILE* file) const
1288 		{
1289 			fprintf(file,"\t\tmh %i ", holeUVCount);
1290 			for(int i=0; i<holeUVCount; ++i)
1291 			{
1292 				fprintf(file,"%i", uvIdValue[i]);
1293 				if(i+1<holeUVCount) fprintf(file, " ");
1294 			}
1295 		}
1296 	}mh;
1297 
1298 	/**
1299 	"mu" The first argument refers to the uv set. This is a zero-based
1300 	integer number. The second argument refers to the number of vertices (n)
1301 	on the face which have valid uv values. The last n values are the uv
1302 	ids of the texture coordinates (uvs) for the face. These indices
1303 	are what used to be represented by the "mf" and "mh" specification.
1304 	There may be more than one "mu" specification, one for each unique uv set.
1305 
1306 	Format: {mu uvSet faceUVCount {uvIdValue}}
1307 	*/
1308 	struct MU{
1309 		int uvSet;
1310 		int faceUVCount;
1311 		int* uvIdValue;
1312 
MUpolyFaces::MU1313 		MU()
1314 		{
1315 			uvSet=0;
1316 			faceUVCount=0;
1317 			uvIdValue=0;
1318 		}
1319 
~MUpolyFaces::MU1320 		~MU()
1321 		{
1322 			uvSet=0;
1323 			faceUVCount=0;
1324 			delete [] uvIdValue;
1325 		}
1326 
writepolyFaces::MU1327 		void write(FILE* file) const
1328 		{
1329 			fprintf(file,"\t\tmu %i ", uvSet);
1330 			fprintf(file,"%i ", faceUVCount);
1331 			for(int i=0; i<faceUVCount; ++i)
1332 			{
1333 				fprintf(file,"%i", uvIdValue[i]);
1334 				if(i+1<faceUVCount) fprintf(file, " ");
1335 			}
1336 		}
1337 	};
1338 
1339     MU* mu;
1340     size_t muCount;
1341 
1342     /**
1343     "mc" The first argument refers to the color set. This is a zero-based
1344     integer number. The second argument refers to the number of vertices (n)
1345     on the face which have valid color values. The last n values are the color
1346     ids of the colors for the face.
1347     There may be more than one "mc" specification, one for each unique color set.
1348 
1349     Format: {mc colorSet faceColorCount {colorIdValue}}
1350     */
1351     struct MC{
1352         int colorSet;
1353         int faceColorCount;
1354         int* colorIdValue;
1355 
MCpolyFaces::MC1356         MC()
1357         {
1358             colorSet=0;
1359             faceColorCount=0;
1360             colorIdValue=0;
1361         }
1362 
~MCpolyFaces::MC1363         ~MC()
1364         {
1365             colorSet=0;
1366             faceColorCount=0;
1367             delete [] colorIdValue;
1368         }
1369 
writepolyFaces::MC1370         void write(FILE* file) const
1371         {
1372             fprintf(file,"\t\tmc %i ", colorSet);
1373             fprintf(file,"%i ", faceColorCount);
1374             for(int i=0; i<faceColorCount; ++i)
1375             {
1376                 fprintf(file,"%i", colorIdValue[i]);
1377                 if(i+1<faceColorCount) fprintf(file, " ");
1378             }
1379         }
1380     };
1381 
1382     MC* mc;
1383     size_t mcCount;
1384 
1385     /**
1386 	"fc" specifies the color index values for a face
1387 
1388 	Format: {fc faceColorCount {colorIndexValue}}
1389 	*/
1390 	struct FC{
1391 		int faceColorCount;
1392 		int* colorIndexValue;
1393 
FCpolyFaces::FC1394 		FC()
1395 		{
1396 			faceColorCount=0;
1397 			colorIndexValue=0;
1398 		}
~FCpolyFaces::FC1399 		~FC()
1400 		{
1401 			faceColorCount=0;
1402 			delete [] colorIndexValue;
1403 		}
1404 
writepolyFaces::FC1405 		void write(FILE* file) const
1406 		{
1407 			fprintf(file,"\t\tfc %i ", faceColorCount);
1408 			for(int i=0; i<faceColorCount; ++i)
1409 			{
1410 				fprintf(file,"%i", colorIndexValue[i]);
1411 				if(i+1<faceColorCount) fprintf(file, " ");
1412 			}
1413 		}
1414 	}fc;
1415 
polyFacespolyFaces1416     polyFaces ()
1417     {
1418         mcCount = 0;
1419         mc = 0;
1420         muCount = 0;
1421         mu = 0;
1422     }
1423 
~polyFacespolyFaces1424     ~polyFaces ()
1425     {
1426         muCount = 0;
1427         delete[] mu;
1428         mcCount = 0;
1429         delete[] mc;
1430     }
1431 
writepolyFaces1432 	void write(FILE* file) const
1433 	{
1434 		if(f.faceEdgeCount)
1435 		{
1436             fprintf(file, "\n");
1437 			f.write(file);
1438 		}
1439 		if(h.holeEdgeCount)
1440 		{
1441 			fprintf(file, "\n");
1442 			h.write(file);
1443 
1444 		}
1445 		if(mf.faceUVCount)
1446 		{
1447 			fprintf(file, "\n");
1448 			mf.write(file);
1449 		}
1450 		if(mh.holeUVCount)
1451 		{
1452 			fprintf(file, "\n");
1453 			mh.write(file);
1454 		}
1455         if ( muCount > 0 )
1456         {
1457             for ( size_t i=0; i<muCount; ++i )
1458             {
1459                 if(mu[i].faceUVCount)
1460                 {
1461                     fprintf(file, "\n");
1462                     mu[i].write(file);
1463                 }
1464             }
1465         }
1466         if ( mcCount > 0 )
1467         {
1468             for ( size_t i=0; i<mcCount; ++i )
1469             {
1470                 if(mc[i].faceColorCount)
1471                 {
1472                     fprintf(file, "\n");
1473                     mc[i].write(file);
1474                 }
1475             }
1476         }
1477 		if(fc.faceColorCount)
1478 		{
1479 			fprintf(file, "\n");
1480 			fc.write(file);
1481 		}
1482 	}
1483 };
1484 
1485 /**
1486 Polygonal mesh
1487 
1488 Value Syntax
1489 	{string [int {double double double}]}
1490 	{string [int {double double double}]}
1491 	[{string [int {double double}]}]
1492 	{string [int {double double string}]}
1493 
1494 Value Meaning
1495 	"v" [vertexCount {vertexX vertexY vertexZ}]
1496 	"vn" [normalCount {normalX normalY normalZ}]
1497 	["vt" [uvCount {uValue vValue}]]
1498 	"e" [edgeCount {startVertex endVertex "smooth"|"hard"}]
1499 
1500 Example
1501 	setAttr node.meshAttr -type mesh "v" 3 0 0 0 0 1 0 0 0 1
1502 		"vn" 3 1 0 0 1 0 0 1 0 0
1503 		"vt" 3 0 0 0 1 1 0
1504 		"e" 3 0 1 "hard" 1 2 "hard" 2 0 "hard";
1505 */
1506 struct mesh
1507 {
1508 	/** "v" specifies the vertices of the polygonal mesh*/
1509 	struct V
1510 	{
1511 		int vertexCount;
1512 		double* vertices;
1513 
Vmesh::V1514 		V()
1515 		{
1516 			vertexCount = 0;
1517 			vertices = 0;
1518 		}
1519 
~Vmesh::V1520 		~V()
1521 		{
1522 			vertexCount = 0;
1523 			delete [] vertices;
1524 		}
1525 
writemesh::V1526 		void write(FILE* file) const
1527 		{
1528 			fprintf(file,"\"v\" %i ", vertexCount);
1529 			size_t size = vertexCount * 3;
1530 			for(size_t i=0; i<size; ++i)
1531 			{
1532 				fprintf(file,"%f", vertices[i]);
1533 				if(i+1<size) fprintf(file," ");
1534 			}
1535 		}
1536 	}v;
1537 
1538 	/** "vn" specifies the normal of each vertex*/
1539 	struct VN
1540 	{
1541 		int normalCount;
1542 		double* normals;
1543 
VNmesh::VN1544 		VN()
1545 		{
1546 			normalCount = 0;
1547 			normals = 0;
1548 		}
1549 
~VNmesh::VN1550 		~VN()
1551 		{
1552 			normalCount = 0;
1553 			delete [] normals;
1554 		}
1555 
writemesh::VN1556 		void write(FILE* file) const
1557 		{
1558 			fprintf(file,"\"vn\" %i ", normalCount);
1559 			size_t size = normalCount * 3;
1560 			for(size_t i=0; i<size; ++i)
1561 			{
1562 				fprintf(file,"%f", normals[i]);
1563 				if(i+1<size) fprintf(file," ");
1564 			}
1565 		}
1566 	}vn;
1567 
1568 	/** "vt" is optional and specifies a U,V texture coordinate for each vertex*/
1569 	struct VT
1570 	{
1571 		int uvCount;
1572 		double* uvValues;
1573 
VTmesh::VT1574 		VT()
1575 		{
1576 			uvCount = 0;
1577 			uvValues = 0;
1578 		}
1579 
~VTmesh::VT1580 		~VT()
1581 		{
1582 			uvCount = 0;
1583 			delete [] uvValues;
1584 		}
1585 
writemesh::VT1586 		void write(FILE* file) const
1587 		{
1588 			fprintf(file,"\"vt\" %i ", uvCount);
1589 			size_t size = uvCount * 2;
1590 			for(size_t i=0; i<size; ++i)
1591 			{
1592 				fprintf(file,"%f", uvValues[i]);
1593 				if(i+1<size) fprintf(file," ");
1594 			}
1595 		}
1596 	}vt;
1597 
1598 	/** "e" specifies the edge connectivity information between vertices*/
1599 	struct E
1600 	{
1601 		int edgeCount;
1602 		struct edge
1603 		{
1604 			enum edgeType
1605 			{
1606 				SMOOTH, HARD
1607 			};
1608 			double startVertex;
1609 			double endVertex;
1610 			edgeType type;
1611 
writemesh::E::edge1612 			void write(FILE* file) const
1613 			{
1614 				fprintf(file, "%f %f ", startVertex, endVertex);
1615 				if(type == HARD)
1616 				{
1617 					fprintf(file, "\"hard\"");
1618 				}else
1619 				{
1620 					fprintf(file, "\"smooth\"");
1621 				}
1622 			}
1623 		}*edges;
1624 
Emesh::E1625 		E()
1626 		{
1627 			edgeCount = 0;
1628 			edges = 0;
1629 		}
1630 
~Emesh::E1631 		~E()
1632 		{
1633 			edgeCount = 0;
1634 			delete [] edges;
1635 		}
1636 
writemesh::E1637 		void write(FILE* file) const
1638 		{
1639 			fprintf(file,"\"e\" %i ", edgeCount);
1640 			for(int i=0; i<edgeCount; ++i)
1641 			{
1642 				edges[i].write(file);
1643 				if(i+1<edgeCount) fprintf(file," ");
1644 			}
1645 		}
1646 	}e;
1647 
writemesh1648 	void write(FILE* file) const
1649 	{
1650 		if(v.vertexCount)
1651 		{
1652 			v.write(file);
1653 			fprintf(file, " ");
1654 		}
1655 		if(vn.normalCount)
1656 		{
1657 			vn.write(file);
1658 			fprintf(file, " ");
1659 		}
1660 		if(vt.uvCount)
1661 		{
1662 			vt.write(file);
1663 			fprintf(file, " ");
1664 		}
1665 		if(e.edgeCount)
1666 		{
1667 			v.write(file);
1668 			fprintf(file, " ");
1669 		}
1670 	}
1671 };
1672 
1673 /**
1674 Lattice data
1675 
1676 Value Syntax
1677 	int int int int
1678 	{double double double}
1679 
1680 Value Meaning
1681 	sDivisionCount tDivisionCount uDivisionCount pointCount
1682 	{pointX pointY pointZ}
1683 
1684 Example
1685 	setAttr node.latticeAttr -type lattice 2 5 2 20
1686 		-2 -2 -2 2 -2 -2 -2 -1 -2 2 -1 -2 -2 0 -2
1687 		2 0 -2 -2 1 -2 2 1 -2 -2 2 -2 2 2 -2
1688 		-2 -2 2 2 -2 2 -2 -1 2 2 -1 2 -2 0 2
1689 		2 0 2 -2 1 2 2 1 2 -2 2 2 2 2 2;
1690 */
1691 struct lattice
1692 {
1693 	/** sDivisionCount is the horizontal lattice division count*/
1694 	int sDivisionCount;
1695 	/** tDivisionCount is the vertical lattice division count*/
1696 	int tDivisionCount;
1697 	/** uDivisionCount is the depth lattice division count*/
1698 	int uDivisionCount;
1699 	/** pointCount is the total number of lattice points*/
1700 	int	pointCount;
1701 	/** pointX,pointY,pointZ is one lattice point. The list is
1702 	specified varying first in S, then in T, last in U so the
1703 	first two entries are (S=0,T=0,U=0) (s=1,T=0,U=0)
1704 	*/
1705 	double* points;
1706 
latticelattice1707 	lattice()
1708 	{
1709 		sDivisionCount=0;
1710 		tDivisionCount=0;
1711 		uDivisionCount=0;
1712 		pointCount=0;
1713 		points = 0;
1714 	}
~latticelattice1715 	~lattice()
1716 	{
1717 		sDivisionCount=0;
1718 		tDivisionCount=0;
1719 		uDivisionCount=0;
1720 		pointCount=0;
1721 		delete [] points;
1722 	}
1723 
writelattice1724 	void write(FILE* file) const
1725 	{
1726 		fprintf(file,"%i %i %i %i ", sDivisionCount, tDivisionCount, uDivisionCount, pointCount);
1727 		size_t size = pointCount*3;
1728 		for(size_t i = 0; i<size; ++i)
1729 		{
1730 			fprintf(file, "%f", points[i]);
1731 			if(i+1<size) fprintf(file, " ");
1732 		}
1733 	}
1734 };
1735 
1736 // Predefined variables
1737 const bool on=true;
1738 const bool off=false;
1739 const bool yes=true;
1740 const bool no=false;
1741 
1742 }//namespace MayaDM
1743 #endif // __MayaDM_TYPES_H__