Main Page | Class Hierarchy | Class List | Directories | File List | Class Members

SurfaceGenerator.cpp

00001 
00006 #include "SurfaceGenerator.h"
00007 
00008 
00009 //all the attributes for the ImplicitSphere
00010 MObject SurfaceGenerator::ellipsoid_Radius;
00011 MObject SurfaceGenerator::ellipsoid_TWorldMatrix;
00012 MObject SurfaceGenerator::ellipsoid_Weight;
00013 MObject SurfaceGenerator::ellipsoid_BBoxMin;
00014 MObject SurfaceGenerator::ellipsoid_BBoxMax;
00015 
00016 //surface extraction attributes
00017 MObject SurfaceGenerator::tessellation;
00018 MObject SurfaceGenerator::isolevel;
00019 MObject SurfaceGenerator::algorithm;
00020 
00021 //the ImplicitSpheres 
00022 std::vector<int> SurfaceGenerator::activeIS;
00023 std::map<int,ImplicitSphere*> SurfaceGenerator::implicit;
00024 
00025 
00026 
00027 //for the mesh creation
00028 MPointArray SurfaceGenerator::vertexArray;
00029 MIntArray       SurfaceGenerator::polygonCount;
00030 MIntArray       SurfaceGenerator::polygonConnects;
00031 
00032 //data values of the 3D volume
00033 std::vector<CORNER> SurfaceGenerator::allPoints;
00034 std::vector<CUBE> SurfaceGenerator::cubes;
00035 
00036 
00037 
00038 //the output attribute
00039 MObject SurfaceGenerator::out_mesh;
00040 
00041 
00042 const MTypeId SurfaceGenerator::typeId(0x80000);
00043 
00044 const MString SurfaceGenerator::typeName("SurfaceGenerator");
00045 
00046 int SurfaceGenerator::indexToVertex(MPoint p) {
00047         //need to use this method as the API overloading of ==
00048         //for an MPoint object is incorrect
00049         for(int i = 0; i < vertexArray.length() ; i++) {
00050                 if(vertexArray[i].x < p.x+0.001 && vertexArray[i].x > p.x-0.001)
00051                 if(vertexArray[i].y < p.y+0.001 && vertexArray[i].y > p.y-0.001)
00052                         if(vertexArray[i].z < p.z+0.001 && vertexArray[i].z > p.z-0.001)
00053                                         return i;
00054 
00055         }
00056         return -1;
00057 }
00058 
00059 /*
00060 * Implementation from Paul Bourke slightly adapted to work with this plug-in
00061 */
00062 MPoint SurfaceGenerator::interpolate(double isolevel,CORNER *p1, CORNER *p2) {
00063         MPoint p;
00064         //
00065         if(std::abs(isolevel-p1->value) < 0.00001)
00066                 return p1->point;
00067         if(std::abs(isolevel-p2->value) < 0.00001)
00068                 return p2->point;
00069         if(std::abs(p1->value-p2->value) < 0.00001)
00070                 return p1->point;
00071         double mu = (isolevel - p1->value)/(p2->value -p1->value);
00072         p.x = p1->point.x + (mu * (p2->point.x - p1->point.x));
00073         p.y = p1->point.y + (mu * (p2->point.y - p1->point.y));
00074         p.z = p1->point.z + (mu * (p2->point.z - p1->point.z));
00075         return p;
00076 }
00077 
00078 /*
00079 * Implementation from Paul Bourke slightly adapted to work with this plug-in
00080 */
00081 int SurfaceGenerator::polygoniseTri(CUBE cube, double iso, int v0, int v1, int v2, int v3) {
00082         //Number of trinagles
00083         int ntri = 0;
00084         int triindex;
00085         
00086         triindex = 0;
00087         if(cube.corners[v0]->value < iso) triindex |= 1;
00088         if(cube.corners[v1]->value < iso) triindex |= 2;
00089         if(cube.corners[v2]->value < iso) triindex |= 4;
00090         if(cube.corners[v3]->value < iso) triindex |= 8;
00091 
00092         switch (triindex) {
00093                 case 0x00:
00094                 case 0x0F:
00095                         break;
00096                 
00097                 case 0x0E:
00098                 case 0x01:
00099                         {
00100                         MPoint p1 = interpolate(iso,cube.corners[v0],cube.corners[v1]);
00101                         MPoint p2 = interpolate(iso,cube.corners[v0],cube.corners[v2]);
00102                         MPoint p3 = interpolate(iso,cube.corners[v0],cube.corners[v3]);
00103 
00104             int p1Index = indexToVertex(p1);
00105             //check if the point already exist if not
00106             //add it to the array
00107             if(p1Index == -1) {
00108                 p1Index = vertexArray.length();
00109                 vertexArray.insert(p1,p1Index);
00110             }
00111 
00112             int p2Index = indexToVertex(p2);
00113             if(p2Index == -1) {
00114                 p2Index = vertexArray.length();
00115                 vertexArray.insert(p2,p2Index);
00116             }
00117 
00118             int p3Index = indexToVertex(p3);
00119             if(p3Index == -1) {
00120                 p3Index = vertexArray.length();
00121                 vertexArray.insert(p3,p3Index);
00122             }
00123                         
00124                         //the added polygon is going to be
00125                         //3 points
00126                         polygonCount.append(3);
00127                         //add the connection of these 3 points
00128                         polygonConnects.append(p1Index);
00129                         polygonConnects.append(p2Index);
00130                         polygonConnects.append(p3Index);
00131 
00132                         }
00133                         break;
00134 
00135                 case 0x0D:
00136                 case 0x02:
00137                         {
00138                         MPoint p1 = interpolate(iso,cube.corners[v1],cube.corners[v0]);
00139                         MPoint p2 = interpolate(iso,cube.corners[v1],cube.corners[v3]);
00140                         MPoint p3 = interpolate(iso,cube.corners[v1],cube.corners[v2]);
00141 
00142                         int p1Index = indexToVertex(p1);
00143             if(p1Index == -1) {
00144                 p1Index = vertexArray.length();
00145                 vertexArray.insert(p1,p1Index);
00146             }
00147 
00148             int p2Index = indexToVertex(p2);
00149             if(p2Index == -1) {
00150                 p2Index = vertexArray.length();
00151                 vertexArray.insert(p2,p2Index);
00152             }
00153 
00154             int p3Index = indexToVertex(p3);
00155             if(p3Index == -1) {
00156                 p3Index = vertexArray.length();
00157                 vertexArray.insert(p3,p3Index);
00158             }
00159 
00160                         polygonCount.append(3);
00161                         polygonConnects.append(p1Index);
00162                         polygonConnects.append(p2Index);
00163                         polygonConnects.append(p3Index);
00164 
00165                         }
00166                         break;
00167                 
00168                 case 0x0C:
00169                 case 0x03:
00170                         {
00171                         MPoint p1 = interpolate(iso,cube.corners[v0],cube.corners[v3]);
00172                         MPoint p2 = interpolate(iso,cube.corners[v0],cube.corners[v2]);
00173                         MPoint p3 = interpolate(iso,cube.corners[v1],cube.corners[v3]);
00174 
00175                         int p1Index = indexToVertex(p1);
00176             if(p1Index == -1) {
00177                 p1Index = vertexArray.length();
00178                 vertexArray.insert(p1,p1Index);
00179             }
00180 
00181             int p2Index = indexToVertex(p2);
00182             if(p2Index == -1) {
00183                 p2Index = vertexArray.length();
00184                 vertexArray.insert(p2,p2Index);
00185             }
00186 
00187             int p3Index = indexToVertex(p3);
00188             if(p3Index == -1) {
00189                 p3Index = vertexArray.length();
00190                 vertexArray.insert(p3,p3Index);
00191             }
00192 
00193                         polygonCount.append(3);
00194                         polygonConnects.append(p1Index);
00195                         polygonConnects.append(p2Index);
00196                         polygonConnects.append(p3Index);
00197 
00198             MPoint p4 = interpolate(iso,cube.corners[v1],cube.corners[v2]);
00199 
00200             int p4Index = indexToVertex(p4);
00201             if(p4Index == -1) {
00202                 p4Index = vertexArray.length();
00203                 vertexArray.insert(p4,p4Index);
00204             }
00205 
00206             polygonCount.append(3);
00207             polygonConnects.append(p3Index);
00208             polygonConnects.append(p4Index);
00209             polygonConnects.append(p2Index);
00210                         }
00211                         break;
00212 
00213                 case 0x0B:
00214                 case 0x04:
00215                         {
00216                         MPoint p1 = interpolate(iso,cube.corners[v2],cube.corners[v0]);
00217                         MPoint p2 = interpolate(iso,cube.corners[v2],cube.corners[v1]);
00218                         MPoint p3 = interpolate(iso,cube.corners[v2],cube.corners[v3]);
00219 
00220                         int p1Index = indexToVertex(p1);
00221             if(p1Index == -1) {
00222                 p1Index = vertexArray.length();
00223                 vertexArray.insert(p1,p1Index);
00224             }
00225 
00226             int p2Index = indexToVertex(p2);
00227             if(p2Index == -1) {
00228                 p2Index = vertexArray.length();
00229                 vertexArray.insert(p2,p2Index);
00230             }
00231 
00232             int p3Index = indexToVertex(p3);
00233             if(p3Index == -1) {
00234                 p3Index = vertexArray.length();
00235                 vertexArray.insert(p3,p3Index);
00236             }
00237 
00238                         polygonCount.append(3);
00239                         polygonConnects.append(p1Index);
00240                         polygonConnects.append(p2Index);
00241                         polygonConnects.append(p3Index);
00242                         
00243                         }
00244                         break;  
00245                         
00246                 case 0x0A:
00247                 case 0x05:
00248                         {
00249                         MPoint p1 = interpolate(iso,cube.corners[v0],cube.corners[v1]);
00250                         MPoint p2 = interpolate(iso,cube.corners[v2],cube.corners[v3]);
00251                         MPoint p3 = interpolate(iso,cube.corners[v0],cube.corners[v3]);
00252 
00253                         int p1Index = indexToVertex(p1);
00254             if(p1Index == -1) {
00255                 p1Index = vertexArray.length();
00256                 vertexArray.insert(p1,p1Index);
00257             }
00258 
00259             int p2Index = indexToVertex(p2);
00260             if(p2Index == -1) {
00261                 p2Index = vertexArray.length();
00262                 vertexArray.insert(p2,p2Index);
00263             }
00264 
00265             int p3Index = indexToVertex(p3);
00266             if(p3Index == -1) {
00267                 p3Index = vertexArray.length();
00268                 vertexArray.insert(p3,p3Index);
00269             }
00270 
00271                         polygonCount.append(3);
00272                         polygonConnects.append(p1Index);
00273                         polygonConnects.append(p2Index);
00274                         polygonConnects.append(p3Index);
00275 
00276 
00277 
00278                         MPoint p4 = interpolate(iso,cube.corners[v1],cube.corners[v2]);
00279 
00280                         int p4Index = indexToVertex(p4);
00281             if(p4Index == -1) {
00282                 p4Index = vertexArray.length();
00283                 vertexArray.insert(p4,p4Index);
00284             }
00285 
00286                         polygonCount.append(3);
00287                         polygonConnects.append(p1Index);
00288                         polygonConnects.append(p4Index);
00289                         polygonConnects.append(p2Index);
00290                         }
00291                         break;
00292 
00293                 case 0x09:
00294                 case 0x06:
00295                         {
00296                         MPoint p1 = interpolate(iso,cube.corners[v0],cube.corners[v1]);
00297                         MPoint p2 = interpolate(iso,cube.corners[v1],cube.corners[v3]);
00298                         MPoint p3 = interpolate(iso,cube.corners[v2],cube.corners[v3]);
00299 
00300                         int p1Index = indexToVertex(p1);
00301             if(p1Index == -1) {
00302                 p1Index = vertexArray.length();
00303                 vertexArray.insert(p1,p1Index);
00304             }
00305 
00306             int p2Index = indexToVertex(p2);
00307             if(p2Index == -1) {
00308                 p2Index = vertexArray.length();
00309                 vertexArray.insert(p2,p2Index);
00310             }
00311 
00312             int p3Index = indexToVertex(p3);
00313             if(p3Index == -1) {
00314                 p3Index = vertexArray.length();
00315                 vertexArray.insert(p3,p3Index);
00316             }
00317 
00318                         polygonCount.append(3);
00319                         polygonConnects.append(p1Index);
00320                         polygonConnects.append(p2Index);
00321                         polygonConnects.append(p3Index);
00322 
00323 
00324 
00325                         MPoint p4 = interpolate(iso,cube.corners[v0],cube.corners[v2]);
00326 
00327                         int p4Index = indexToVertex(p4);
00328             if(p4Index == -1) {
00329                 p4Index = vertexArray.length();
00330                 vertexArray.insert(p4,p4Index);
00331             }
00332 
00333                         polygonCount.append(3);
00334                         polygonConnects.append(p1Index);
00335                         polygonConnects.append(p4Index);
00336                         polygonConnects.append(p3Index);
00337                         }
00338                         break;
00339                         
00340                 case 0x07:
00341                 case 0x08:
00342                         {
00343                         MPoint p1 = interpolate(iso,cube.corners[v3],cube.corners[v0]);
00344                         MPoint p2 = interpolate(iso,cube.corners[v3],cube.corners[v2]);
00345                         MPoint p3 = interpolate(iso,cube.corners[v3],cube.corners[v1]);
00346                         
00347                         int p1Index = indexToVertex(p1);
00348             if(p1Index == -1) {
00349                 p1Index = vertexArray.length();
00350                 vertexArray.insert(p1,p1Index);
00351             }
00352 
00353             int p2Index = indexToVertex(p2);
00354             if(p2Index == -1) {
00355                 p2Index = vertexArray.length();
00356                 vertexArray.insert(p2,p2Index);
00357             }
00358 
00359             int p3Index = indexToVertex(p3);
00360             if(p3Index == -1) {
00361                 p3Index = vertexArray.length();
00362                 vertexArray.insert(p3,p3Index);
00363             }
00364                         
00365                         polygonCount.append(3);
00366                         polygonConnects.append(p1Index);
00367                         polygonConnects.append(p2Index);
00368                         polygonConnects.append(p3Index);
00369                         
00370                         }
00371                         break;  
00372                         
00373         }
00374         
00375         return ntri;
00376         
00377 }
00378 /*
00379 * Implementation from Paul Bourke slightly adapted to work with this plug-in
00380 */
00381 int SurfaceGenerator::polygonise(CUBE cube, double iso) {
00382    int i,ntriang;
00383    int cubeindex;
00384    MPoint vertlist[12];
00385 
00386         int edgeTable[256]={
00387         0x0  , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
00388         0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
00389         0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
00390         0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
00391         0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
00392         0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
00393         0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
00394         0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
00395         0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
00396         0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
00397         0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
00398         0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
00399         0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
00400         0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
00401         0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
00402         0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
00403         0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
00404         0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
00405         0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
00406         0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
00407         0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
00408         0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
00409         0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
00410         0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
00411         0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
00412         0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
00413         0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
00414         0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
00415         0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
00416         0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
00417         0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
00418         0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0   };
00419         int triTable[256][16] =
00420         {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00421         {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00422         {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00423         {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00424         {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00425         {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00426         {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00427         {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
00428         {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00429         {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00430         {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00431         {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
00432         {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00433         {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
00434         {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
00435         {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00436         {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00437         {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00438         {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00439         {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
00440         {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00441         {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
00442         {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
00443         {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
00444         {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00445         {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
00446         {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
00447         {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
00448         {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
00449         {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
00450         {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
00451         {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
00452         {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00453         {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00454         {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00455         {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
00456         {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00457         {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
00458         {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
00459         {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
00460         {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00461         {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
00462         {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
00463         {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
00464         {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
00465         {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
00466         {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
00467         {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
00468         {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00469         {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
00470         {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
00471         {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00472         {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
00473         {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
00474         {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
00475         {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
00476         {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
00477         {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
00478         {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
00479         {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
00480         {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
00481         {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
00482         {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
00483         {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00484         {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00485         {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00486         {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00487         {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
00488         {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00489         {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
00490         {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
00491         {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
00492         {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00493         {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
00494         {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
00495         {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
00496         {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
00497         {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
00498         {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
00499         {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
00500         {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00501         {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
00502         {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
00503         {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
00504         {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
00505         {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
00506         {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
00507         {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
00508         {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
00509         {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
00510         {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
00511         {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
00512         {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
00513         {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
00514         {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
00515         {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
00516         {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00517         {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
00518         {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
00519         {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
00520         {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
00521         {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
00522         {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00523         {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
00524         {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
00525         {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
00526         {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
00527         {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
00528         {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
00529         {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
00530         {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
00531         {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00532         {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
00533         {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
00534         {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
00535         {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
00536         {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
00537         {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
00538         {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
00539         {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00540         {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
00541         {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
00542         {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
00543         {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
00544         {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
00545         {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00546         {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
00547         {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00548         {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00549         {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00550         {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00551         {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
00552         {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00553         {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
00554         {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
00555         {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
00556         {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00557         {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
00558         {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
00559         {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
00560         {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
00561         {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
00562         {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
00563         {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
00564         {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00565         {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
00566         {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
00567         {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
00568         {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
00569         {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
00570         {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
00571         {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
00572         {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
00573         {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00574         {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
00575         {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
00576         {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
00577         {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
00578         {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
00579         {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00580         {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00581         {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
00582         {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
00583         {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
00584         {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
00585         {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
00586         {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
00587         {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
00588         {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
00589         {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
00590         {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
00591         {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
00592         {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
00593         {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
00594         {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
00595         {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
00596         {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
00597         {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
00598         {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
00599         {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
00600         {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
00601         {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
00602         {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
00603         {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
00604         {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
00605         {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
00606         {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
00607         {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00608         {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
00609         {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
00610         {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00611         {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00612         {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00613         {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
00614         {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
00615         {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
00616         {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
00617         {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
00618         {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
00619         {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
00620         {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
00621         {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
00622         {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
00623         {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
00624         {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00625         {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
00626         {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
00627         {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00628         {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
00629         {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
00630         {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
00631         {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
00632         {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
00633         {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
00634         {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
00635         {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00636         {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
00637         {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
00638         {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
00639         {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
00640         {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
00641         {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00642         {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
00643         {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00644         {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
00645         {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
00646         {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
00647         {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
00648         {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
00649         {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
00650         {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
00651         {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
00652         {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
00653         {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
00654         {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
00655         {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00656         {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
00657         {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
00658         {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00659         {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00660         {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00661         {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
00662         {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
00663         {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00664         {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
00665         {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
00666         {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00667         {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00668         {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
00669         {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00670         {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
00671         {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00672         {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00673         {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00674         {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00675         {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}};
00676 
00677    /*
00678       Determine the index into the edge table which
00679       tells us which vertices are inside of the surface
00680    */
00681    cubeindex = 0;
00682    if (cube.corners[0]->value < iso) cubeindex |= 1;
00683    if (cube.corners[1]->value < iso) cubeindex |= 2;
00684    if (cube.corners[2]->value < iso) cubeindex |= 4;
00685    if (cube.corners[3]->value < iso) cubeindex |= 8;
00686    if (cube.corners[4]->value < iso) cubeindex |= 16;
00687    if (cube.corners[5]->value < iso) cubeindex |= 32;
00688    if (cube.corners[6]->value < iso) cubeindex |= 64;
00689    if (cube.corners[7]->value < iso) cubeindex |= 128;
00690 
00691    /* Cube is entirely in/out of the surface */
00692    if (edgeTable[cubeindex] == 0)
00693       return(0);
00694 
00695    /* Find the vertices where the surface intersects the cube */
00696    if (edgeTable[cubeindex] & 1)
00697       vertlist[0] = interpolate(iso,cube.corners[0],cube.corners[1]);
00698 
00699    if (edgeTable[cubeindex] & 2)
00700       vertlist[1] = interpolate(iso,cube.corners[1],cube.corners[2]);
00701 
00702    if (edgeTable[cubeindex] & 4)
00703       vertlist[2] = interpolate(iso,cube.corners[2],cube.corners[3]);
00704 
00705    if (edgeTable[cubeindex] & 8)
00706       vertlist[3] = interpolate(iso,cube.corners[3],cube.corners[0]);
00707 
00708    if (edgeTable[cubeindex] & 16)
00709       vertlist[4] = interpolate(iso,cube.corners[4],cube.corners[5]);
00710 
00711    if (edgeTable[cubeindex] & 32)
00712       vertlist[5] = interpolate(iso,cube.corners[5],cube.corners[6]);
00713 
00714    if (edgeTable[cubeindex] & 64)
00715       vertlist[6] = interpolate(iso,cube.corners[6],cube.corners[7]);
00716 
00717    if (edgeTable[cubeindex] & 128)
00718       vertlist[7] = interpolate(iso,cube.corners[7],cube.corners[4]);
00719 
00720    if (edgeTable[cubeindex] & 256)
00721       vertlist[8] = interpolate(iso,cube.corners[0],cube.corners[4]);
00722 
00723    if (edgeTable[cubeindex] & 512)
00724       vertlist[9] = interpolate(iso,cube.corners[1],cube.corners[5]);
00725 
00726    if (edgeTable[cubeindex] & 1024)
00727       vertlist[10] = interpolate(iso,cube.corners[2],cube.corners[6]);
00728 
00729    if (edgeTable[cubeindex] & 2048)
00730       vertlist[11] = interpolate(iso,cube.corners[3],cube.corners[7]);
00731 
00732 
00733    /* Create the triangle */
00734    ntriang = 0;
00735    for (i=0;triTable[cubeindex][i]!=-1;i+=3) {
00736       MPoint p1 = vertlist[triTable[cubeindex][i  ]];
00737       MPoint p2 = vertlist[triTable[cubeindex][i+1]];
00738       MPoint p3 = vertlist[triTable[cubeindex][i+2]];
00739 
00740         int p1Index = indexToVertex(p1);
00741         //check if the point already exist if not
00742         //add it to the array
00743         if(p1Index == -1) {
00744             p1Index = vertexArray.length();
00745             vertexArray.insert(p1,p1Index);
00746         }
00747 
00748         int p2Index = indexToVertex(p2);
00749         if(p2Index == -1) {
00750             p2Index = vertexArray.length();
00751             vertexArray.insert(p2,p2Index);
00752         }
00753 
00754         int p3Index = indexToVertex(p3);
00755         if(p3Index == -1) {
00756             p3Index = vertexArray.length();
00757             vertexArray.insert(p3,p3Index);
00758         }
00759                 //the added polygon is going to be
00760                 //3 points
00761                 polygonCount.append(3);
00762                 //add the connection of these 3 points
00763                 polygonConnects.append(p3Index);
00764                 polygonConnects.append(p2Index);
00765                 polygonConnects.append(p1Index);
00766 
00767       ntriang++;
00768    }
00769 
00770    return(ntriang);
00771 
00772 }
00773 
00774 
00775 
00776 MStatus SurfaceGenerator::compute(const MPlug& plug, MDataBlock& data) {
00777         //global status declaration
00778     MStatus stat;
00779     
00780     MString space(" ");
00781     
00782     if(plug == out_mesh) {
00783         //Get out the isolevel
00784         MDataHandle inputIso = data.inputValue(isolevel,&stat);
00785         double iso = inputIso.asDouble();
00786                 
00787                 //get all the array attributes
00788         MArrayDataHandle inputERadius = data.inputArrayValue(ellipsoid_Radius,&stat);
00789         if(!stat) {
00790             return stat;
00791         }
00792         MArrayDataHandle inputEWMatrix = data.inputArrayValue(ellipsoid_TWorldMatrix,&stat);
00793         if(!stat) {
00794             return stat;
00795         }
00796         MArrayDataHandle inputEWeight = data.inputArrayValue(ellipsoid_Weight,&stat);
00797         if(!stat) {
00798             return stat;
00799         }
00800                 
00801                 /* Need to test if we have the same amount of elements */
00802         unsigned int ier = inputERadius.elementCount(&stat);
00803         if(!stat) {
00804             return stat;
00805         }
00806 
00807        unsigned int iewm = inputEWMatrix.elementCount(&stat);
00808        if(!stat) {
00809             return stat;
00810         }
00811 
00812         unsigned int iew = inputEWeight.elementCount(&stat);
00813        if(!stat) {
00814             return stat;
00815         }
00816                 
00817                 //test that we have the same abount of elements
00818         if(ier != iewm && iewm != iew) {
00819             return MStatus::kFailure;
00820         }
00821         
00822         /*
00823         * Get the Min and Max of each of the bounding boxes for the 3D volume
00824         */
00825 
00826         MArrayDataHandle inputBBMin = data.inputArrayValue(ellipsoid_BBoxMin,&stat);
00827         unsigned int ibbmin = inputBBMin.elementCount(&stat);
00828         MPoint minP(0,0,0);
00829         int i=0;
00830         for(i=0; i < ibbmin ; i++) {
00831                 stat = inputBBMin.jumpToElement(i);
00832                 if(stat != MS::kSuccess) {
00833                         return MS::kFailure;
00834                 } else {
00835                         MDataHandle tMin = inputBBMin.inputValue(&stat);
00836                         double3 &point = tMin.asDouble3();
00837 
00838                         if(minP.x > point[0] || i==0) {
00839                                 minP.x = point[0];
00840                         }
00841                         
00842                         if(minP.y > point[1] || i==0) {
00843                                 minP.y = point[1];
00844                         }
00845                         
00846                         if(minP.z > point[2] || i==0) {
00847                                 minP.z = point[2];
00848                         }
00849                         
00850                 }
00851         }
00852         
00853         MArrayDataHandle inputBBMax = data.inputArrayValue(ellipsoid_BBoxMax,&stat);
00854         unsigned int ibbmax = inputBBMax.elementCount(&stat);
00855         MPoint maxP(0,0,0);
00856         for(i=0; i < ibbmax ; i++) {
00857                 stat = inputBBMax.jumpToElement(i);
00858                 if(stat != MS::kSuccess) {
00859                         return MS::kFailure;
00860                 } else {
00861                         MDataHandle tMax = inputBBMax.inputValue(&stat);
00862                         double3 &point = tMax.asDouble3();
00863                         
00864                         if(maxP.x < point[0] || i==0) {
00865                                 maxP.x = point[0];
00866                         }
00867                         
00868                         if(maxP.y < point[1] || i==0) {
00869                                 maxP.y = point[1];
00870                         }
00871                         
00872                         if(maxP.z < point[2] || i==0) {
00873                                 maxP.z = point[2];
00874                         }
00875                 }
00876         }
00877         
00878         /*
00879         * Get the tessellation split up the cube
00880         */
00881         MDataHandle inputTess = data.inputValue(tessellation,&stat);
00882         unsigned int tess = inputTess.asInt();
00883         double tessX = std::abs((minP.x-maxP.x) / tess);
00884         double tessY = std::abs((minP.y-maxP.y) / tess);
00885         double tessZ = std::abs((minP.z-maxP.z) / tess);
00886         
00887 
00888         /*
00889         * Clear all the arrays for the mesh
00890         */
00891         vertexArray.clear();
00892         polygonCount.clear();
00893         polygonConnects.clear();
00894         
00895         /*
00896         * Clear all the vectors to create the mesh
00897         */
00898         allPoints.clear();
00899         cubes.clear();
00900                 activeIS.clear();
00901                 //howmany steps completed
00902         int step = 0;
00903         
00904         
00905         /*
00906         * Load the implicit functions
00907         */
00908         
00909         for(int a = 0; a < iew; ++a) {
00910                                                 
00911                         stat = inputERadius.jumpToElement(a);
00912                         MStatus stat2 = inputEWMatrix.jumpToElement(a);
00913                         MStatus stat3 = inputEWeight.jumpToElement(a);
00914 
00915                         if(stat != MS::kSuccess && stat2 != MS::kSuccess && stat3 != MS::kSuccess) {
00916                                 return MS::kFailure;
00917                         } else {
00918                                 
00919                                 MDataHandle iEr = inputERadius.inputValue(&stat);
00920                                 if(stat != MS::kSuccess) {
00921                                         return MS::kFailure;
00922                                         
00923                                 } else {
00924                                         MDistance dist = iEr.asDistance();
00925                                         MDataHandle iEm = inputEWMatrix.inputValue(&stat);
00926                                         
00927                                         if(stat != MS::kSuccess) {
00928                                                 return MS::kFailure;
00929                                         
00930                                         } else {
00931                                                 MMatrix matrix = iEm.asMatrix();
00932                                                 MDataHandle iEw = inputEWeight.inputValue(&stat);
00933                                                 
00934                                                 if(stat != MS::kSuccess) {
00935                                                         return MS::kFailure;
00936                                                 
00937                                                 } else {
00938                                                         float weight = iEw.asFloat();
00939                                                         
00940                                                         //get the index of the current element
00941                                                         int index = inputERadius.elementIndex(&stat);
00942         
00943                                                         //check the key if it doesn exist create new
00944                                                         
00945                                                         std::map<int,ImplicitSphere*>::iterator check = implicit.find(index);
00946                                                         
00947                                                         if(check == implicit.end()) {
00948                                                                 ImplicitSphere *sphere = new ImplicitSphere(dist,weight,MPoint(0,0,0));
00949                                                                 sphere->applyMatrix(matrix);
00950                                                                 implicit[index] = sphere;
00951                                                         //else update   
00952                                                         } else {
00953                                                                 implicit[index]->applyMatrix(matrix);
00954                                                                 implicit[index]->applyRadiusWeight(dist,weight);
00955                                                                 
00956                                                         }
00957                                                         //store the active index
00958                                                         activeIS.push_back(index);
00959                                                 }       
00960                                         }
00961                                 }
00962                         }
00963                 }
00964                 
00965                 //all the implicit spheres
00966                 // std::map<int,ImplicitSphere*>::iterator isbegin = implicit.begin();
00967 //         std::map<int,ImplicitSphere*>::iterator isend = implicit.end();
00968                 std::vector<int>::iterator aisbegin = activeIS.begin();
00969                 std::vector<int>::iterator aisend       = activeIS.end();
00970 
00971         
00972                 //need these to have the correct tessalation for both x y z
00973                 double x = minP.x;
00974                 //calculate the iso level for all the vertices
00975                 for(int donex = 0; donex < tess+1; donex++) {
00976                 
00977                 double y = minP.y;
00978                 for(int doney = 0; doney < tess+1; doney++) {
00979                         
00980                         double z = minP.z;
00981                         for(int donez = 0; donez < tess+1; donez++) {
00982                                 
00983                     MPoint point(x,y,z);
00984                     
00985                   
00986                     float vertexTest = -1;
00987                     //If we are for the first time reset vertexTest to the actual value
00988                     bool influenceFirst = false;
00989                     MString Imp("Implicit ");
00990                         
00991                         aisbegin = activeIS.begin();
00992                         
00993                         while(aisbegin != aisend) {
00994 
00995                                                 if(implicit[(*aisbegin)]->testInfluance(point)) {
00996                                                         //check if we influence for the first time
00997                                                         // if yes reset
00998                                                         // if no just add the influence
00999                                                         if(!influenceFirst) {
01000                                                                 vertexTest = implicit[(*aisbegin)]->implicitValue(point);
01001                                                                 influenceFirst = true;
01002                                                         } else {
01003                                                                 vertexTest += implicit[(*aisbegin)]->implicitValue(point);
01004                                                         }
01005                                         
01006                                                 }
01007                                                 aisbegin++;
01008                                         }
01009                                         
01010                                         //create the corner representation
01011                                         CORNER corner;
01012                     corner.point = point;
01013                     corner.value = vertexTest;
01014                     
01015                     if(vertexTest < 0) {
01016                         corner.scase = Outside;
01017                     } else if(vertexTest > 0) {
01018                         corner.scase = Inside;
01019                     } else {
01020                         corner.scase = OnSurface;       
01021                     }
01022                     
01023                     allPoints.insert(allPoints.end(),corner);
01024                   
01025                                         z+=tessZ;
01026                         }
01027                         y+=tessY;
01028                         
01029                 }
01030                 x+=tessX;
01031                 
01032                 step++;
01033         }
01034         
01035 
01036 
01037         
01043         MString corn("Corners ");
01044 
01045         int numPoints = allPoints.size();
01046        
01047 
01048         /*
01049         * Create the cubes only add the once that are OnSurface
01050         */
01051 
01052         std::vector<CORNER>::iterator begin = allPoints.begin();
01053         std::vector<CORNER>::iterator end = allPoints.end();
01054 
01055                 /*
01056                 * need to step through
01057                 */
01058                 
01059         //we step one to many!!!
01060         step-=1;
01061         
01062         //Get the type of algorithm specified by the artist.
01063         MDataHandle inputAlgo = data.inputValue(algorithm,&stat);
01064                 int algo = inputAlgo.asInt();
01065                 
01066         //the position in the allPoints vector
01067         int s = 0;
01068         for(int xdir = 0; xdir < tess; xdir++) {
01069                 for(int ydir = 0; ydir < tess; ydir++) {
01070                         for(int zdir = 0; zdir < tess; zdir++) {
01071                                         //retreive all the corners
01072                                         
01073                                         
01074 
01075                                         CUBE cube;
01076                                         
01077                                         
01078                                         cube.corners[0] = &allPoints[s];
01079                                         cube.corners[1] = &allPoints[((tess+1)*(tess+1))+s]; 
01080                                         cube.corners[2] = &allPoints[((tess+1)*(tess+1))+s+1]; 
01081                                         cube.corners[3] = &allPoints[s+1]; 
01082                                         cube.corners[4] = &allPoints[tess+1+s];
01083                                         cube.corners[5] = &allPoints[((tess+1)*(tess+1))+s+tess+1];
01084                                         cube.corners[6] = &allPoints[((tess+1)*(tess+1))+s+tess+2];
01085                                         cube.corners[7] = &allPoints[tess+2+s];
01086                                         
01087                                         
01088                                         //Polygonise the cube depending on the algorithm
01089                                         if(algo) {
01090                                                 polygoniseTri(cube, iso, 0, 2, 3, 7);
01091                                                 polygoniseTri(cube, iso, 0, 2, 6, 7);
01092                                                 polygoniseTri(cube, iso, 0, 4, 6, 7);
01093                                                 polygoniseTri(cube, iso, 0, 6, 1, 2);
01094                                                 polygoniseTri(cube, iso, 0, 6, 1, 4);
01095                                                 polygoniseTri(cube, iso, 5, 6, 1, 4);
01096                                                 
01097                                         } else {
01098                                                 polygonise(cube,iso);
01099                 
01100                                         }
01101                         
01102                                         
01103                                         //case only 8 vertcies
01104                                         if(numPoints == 8) {
01105                                                 s = numPoints;
01106                                                 
01107                                         }
01108                                         s++;
01109 
01110                                         //finished creating cubes in the zdir
01111                                         if(zdir+1 == tess) {
01112                                                 MString testS("corner ");
01113                                                 //MGlobal::displayInfo(testS + space + s );
01114 
01115                                                 s++;
01116                                                 zdir = tess;
01117                                         }
01118                                         
01119                                         
01120                                         if(ydir+1 == tess && zdir == tess) {
01121                                                 //allready steped in z so all the step for the top row in y
01122                                                 s += (tess + 1);
01123                                                 //MGlobal::displayInfo(corn + s);   
01124                                                 ydir = tess;
01125                                         }
01126                                         
01127                                         if(ydir == tess && zdir == tess && xdir+1 == tess) {
01128                                                 //we are done
01129                                                 xdir = tess;
01130                                         }
01131                         
01132                                 
01133                         }
01134                 }
01135         }
01136 
01137         MObject mesh;
01138                 
01139         MFnMeshData dataCreator;
01140         MObject newOutputData = dataCreator.create(&stat);
01141         
01142         
01143                 
01144                 MFnMesh meshFn;
01145                 //create the mesh               
01146                 meshFn.create(vertexArray.length(), polygonCount.length(), vertexArray, polygonCount, polygonConnects,newOutputData,&stat );
01147 
01148                 MDataHandle outputHandle = data.outputValue(out_mesh);
01149 
01150 
01151 
01152                 outputHandle.set(newOutputData);
01153 
01154                 data.setClean(plug);
01155                 
01156                 
01157                 return MS::kSuccess;
01158     }
01159     
01160 }
01161 
01162 void* SurfaceGenerator::creator() {
01163         return new SurfaceGenerator;
01164 }
01165 
01166 MStatus SurfaceGenerator::initialize(){
01167         
01168     
01169     MStatus stat;
01170     /*
01171     * Set up the weight attributes
01172     */
01173     MFnNumericAttribute nAttr;
01174 
01175         ellipsoid_Weight = nAttr.create("ellipsoid_Weight","ew", MFnNumericData::kFloat, 1.0);
01176     nAttr.setReadable(false);
01177     nAttr.setWritable(true);
01178     //need to have more than one connection
01179     nAttr.setArray(true);
01180     nAttr.setUsesArrayDataBuilder(true);
01181     //so we can add attributes without specifying the index in mel
01182     nAttr.setIndexMatters(false);
01183     //might want to change
01184     nAttr.setKeyable(true);
01185 
01186     stat = addAttribute(ellipsoid_Weight);
01187     // check for error
01188         if( stat != MS::kSuccess ) {
01189                 stat.perror("Unable to attach ew attribute to the SurfaceGenerator node");
01190                 return stat;
01191         }
01192         
01193         /* BoundingBoxMin */
01194         ellipsoid_BBoxMin = nAttr.create("ellipsoid_BBoxMin","bmi", MFnNumericData::k3Double);
01195     nAttr.setReadable(false);
01196     nAttr.setWritable(true);
01197     nAttr.setArray(true);
01198     nAttr.setUsesArrayDataBuilder(true);
01199     nAttr.setIndexMatters(false);
01200     nAttr.setKeyable(true);
01201     
01202     stat = addAttribute(ellipsoid_BBoxMin);
01203      // check for error
01204         if( stat != MS::kSuccess ) {
01205                 stat.perror("Unable to attach bbmin attribute to the SurfaceGenerator node");
01206                 return stat;
01207         }
01208     
01209     /* BoundingBoxMin */
01210     ellipsoid_BBoxMax = nAttr.create("ellipsoid_BBoxMax","bmx", MFnNumericData::k3Double);
01211     nAttr.setReadable(false);
01212     nAttr.setWritable(true);
01213     nAttr.setArray(true);
01214     nAttr.setUsesArrayDataBuilder(true);
01215     nAttr.setIndexMatters(false);
01216     nAttr.setKeyable(true);
01217     
01218     stat = addAttribute(ellipsoid_BBoxMax);
01219      // check for error
01220         if( stat != MS::kSuccess ) {
01221                 stat.perror("Unable to attach bbmax attribute to the SurfaceGenerator node");
01222                 return stat;
01223         }
01224         
01225         /* The tessellation attribute */
01226         tessellation = nAttr.create("tessellation","tes", MFnNumericData::kInt);
01227         //default to 10
01228         nAttr.setDefault(10);
01229     nAttr.setReadable(false);
01230     nAttr.setWritable(true);
01231     nAttr.setKeyable(true);
01232 
01233     stat = addAttribute(tessellation);
01234      // check for error
01235         if( stat != MS::kSuccess ) {
01236                 stat.perror("Unable to attach tessellation attribute to the SurfaceGenerator node");
01237                 return stat;
01238         }
01239         
01240         /* the isolevel */
01241     isolevel = nAttr.create("isolevel","iso", MFnNumericData::kDouble);
01242         //default 10
01243         nAttr.setDefault(0.5);
01244     nAttr.setMin( 0.0 );
01245         nAttr.setMax( 1.0 );
01246     nAttr.setReadable(false);
01247     nAttr.setWritable(true);
01248     nAttr.setKeyable(true);
01249 
01250     stat = addAttribute(isolevel);
01251 
01252     if( stat != MS::kSuccess ) {
01253                 stat.perror("Unable to attach tessellation attribute to the SurfaceGenerator node");
01254                 return stat;
01255         }
01256         
01257         /* The attribute specifying the algorithm to use*/
01258     MFnEnumAttribute enumAttr;
01259     algorithm = enumAttr.create("algorithm","agr");
01260 
01261     MString cubes("Marching Cubes");
01262     MString triangles("Marching Tetrahedrons");
01263     enumAttr.addField(cubes,0);
01264     enumAttr.addField(triangles,1);
01265     enumAttr.setReadable(false);
01266     enumAttr.setWritable(true);
01267     enumAttr.setKeyable(true);
01268 
01269     stat = addAttribute(algorithm);
01270 
01271      // check for error
01272         if( stat != MS::kSuccess ) {
01273                 stat.perror("Unable to attach tessellation attribute to the SurfaceGenerator node");
01274                 return stat;
01275         }
01276         
01277         /*
01278         * The Matrix data
01279         */
01280         
01281         MFnMatrixAttribute mAttr;
01282         
01283         ellipsoid_TWorldMatrix = mAttr.create("ellipsoid_TWorldMatrix","ewm");
01284     mAttr.setReadable(false);
01285     mAttr.setWritable(true);
01286     mAttr.setArray(true);
01287     mAttr.setUsesArrayDataBuilder(true);
01288     mAttr.setIndexMatters(false);
01289     mAttr.setKeyable(true);
01290     
01291     stat = addAttribute(ellipsoid_TWorldMatrix);
01292     
01293     
01294     
01295     // check for error
01296         if( stat != MS::kSuccess ) {
01297                 stat.perror("Unable to attach ewm attribute to the SurfaceGenerator node");
01298                 return stat;
01299         }
01300         
01301         /* The radius attribute */
01302     MFnUnitAttribute fn;
01303         ellipsoid_Radius = fn.create( "ellipsoid_Radius", "r", MFnUnitAttribute::kDistance );
01304 
01305         // set a default value of 1 for the size
01306         fn.setDefault( MDistance(1.0, MDistance::uiUnit()) );
01307         
01308         // set a minim value for the attribute
01309         fn.setMin(0.1f);
01310     fn.setReadable(false);
01311     fn.setWritable(true);
01312     fn.setArray(true);
01313     fn.setUsesArrayDataBuilder(true);
01314     fn.setIndexMatters(false);
01315         fn.setKeyable(true);
01316         // finally add the attribute to this node.
01317         stat = addAttribute(ellipsoid_Radius);
01318         
01319 
01320         // check for error
01321         if( stat != MS::kSuccess ) {
01322                 stat.perror("Unable to attach radius attribute to the softVolumeSphere node");
01323                 return stat;
01324         }
01325         
01326         
01327         MFnTypedAttribute       typedAttr;
01328         
01329         out_mesh = typedAttr.create( "out_mesh", "om",
01330                                                                           MFnData::kMesh);
01331         
01332         typedAttr.setWritable(false);
01333         typedAttr.setStorable(false);
01334     addAttribute(out_mesh);
01335     
01336     
01337     //specify which attributes are needed to recompute the output value
01338     attributeAffects(ellipsoid_Radius, out_mesh);
01339     attributeAffects(ellipsoid_TWorldMatrix, out_mesh);
01340     attributeAffects(ellipsoid_BBoxMax, out_mesh);
01341     attributeAffects(ellipsoid_BBoxMin, out_mesh);
01342     attributeAffects(ellipsoid_Weight, out_mesh);
01343     attributeAffects(tessellation, out_mesh);
01344     attributeAffects(isolevel, out_mesh);
01345     attributeAffects(algorithm, out_mesh);
01346     if( stat != MS::kSuccess ) {
01347                 stat.perror("Unable to attach out_mesh attribute to the softVolumeSphere node");
01348                 return stat;
01349         }
01350     MGlobal::displayInfo("Initialised SurfaceGenerator - By Hannes Ricklefs");
01351 
01352 }
01353 
01354 
01355 

Generated on Mon Jun 13 03:18:00 2005 for ImplicitFunctions by  doxygen 1.4.1