void ToroidalPoloidalProjection::SetFromNode(DataNode *parentNode) { if(parentNode == 0) return; DataNode *searchNode = parentNode->GetNode("ToroidalPoloidalProjection"); if(searchNode == 0) return; DataNode *node; if((node = searchNode->GetNode("R0")) != 0) SetR0(node->AsDouble()); if((node = searchNode->GetNode("r")) != 0) SetR(node->AsDouble()); if((node = searchNode->GetNode("centroidSource")) != 0) { // Allow enums to be int or string in the config file if(node->GetNodeType() == INT_NODE) { int ival = node->AsInt(); if(ival >= 0 && ival < 2) SetCentroidSource(CentroidSource(ival)); } else if(node->GetNodeType() == STRING_NODE) { CentroidSource value; if(CentroidSource_FromString(node->AsString(), value)) SetCentroidSource(value); } } if((node = searchNode->GetNode("centroid")) != 0) SetCentroid(node->AsDoubleArray()); if((node = searchNode->GetNode("project2D")) != 0) SetProject2D(node->AsBool()); }
IX Subsurface( SRFDAT3X *srf, SRFDAT3X sub[] ) { IX nSubSrf; /* number of subsurfaces */ VERTEX3D tmpVrt; /* temporary vertex */ VECTOR3D edge[4]; /* quadrilateral edge vectors */ R8 edgeLength[4]; /* lengths of edges */ R8 cosAngle[4]; /* cosines of angles */ IX obtuse=0; /* identifies obtuse angles */ IX i, j, k; if( srf->shape > 0 ) /* triangle or parallelogram */ { memcpy( sub+0, srf, sizeof(SRFDAT3X) ); /* no subdivision */ sub[0].nr = 0; nSubSrf = 1; } else if( srf->nv==4 ) /* convex quadrilateral */ { for( j=0,i=1; j<4; j++,i++ ) /* compute edge vectors and lengths */ { i &= 3; /* equivalent to: if( i==4 ) i = 0; in this context */ VECTOR( (srf->v+i), (srf->v+j), (edge+j) ); edgeLength[j] = VLEN( (edge+j) ); } for( k=1,j=0,i=3; j<4; j++,i++,k*=2 ) /* compute corner angles */ { i &= 3; /* A dot B = |A|*|B|*cos(angle) */ cosAngle[j] = -VDOT( (edge+j), (edge+i) ) / ( edgeLength[j] * edgeLength[i] ); if( cosAngle[j] < 0.0 ) /* angle > 90 if cos(angle) < 0 */ obtuse += k; } #if( DEBUG > 1 ) for( j=0; j<4; j++ ) { fprintf( _ulog, " edge %d: (%f %f %f) L %f, C %f (%.3f deg)\n", j+1, edge[j].x, edge[j].y, edge[j].z, edgeLength[j], cosAngle[j], acos(cosAngle[j])*RTD ); } fprintf( _ulog, " quadrilateral, case %d\n", obtuse ); fflush( _ulog ); #endif switch (obtuse) /* divide based on number and positions of obtuse angles */ { case 0: /* rectangle */ memcpy( sub+0, srf, sizeof(SRFDAT3X) ); /* no subdivision */ sub[0].nr = 0; nSubSrf = 1; break; case 1: /* only angle 0 is obtuse */ case 4: /* only angle 2 is obtuse */ case 5: /* angles 0 and 2 are obtuse */ case 7: /* angles 0, 1, and 2 are obtuse */ case 13: /* angles 0, 2, and 3 are obtuse */ VCOPY( (srf->v+0), (sub[0].v+0) ); VCOPY( (srf->v+1), (sub[0].v+1) ); VCOPY( (srf->v+2), (sub[0].v+2) ); VCOPY( (srf->v+2), (sub[1].v+0) ); VCOPY( (srf->v+3), (sub[1].v+1) ); VCOPY( (srf->v+0), (sub[1].v+2) ); nSubSrf = 2; break; case 2: /* only angle 1 is obtuse */ case 8: /* only angle 3 is obtuse */ case 10: /* angles 1 and 3 are obtuse */ case 11: /* angles 0, 1, and 3 are obtuse */ case 14: /* angles 1, 2, and 3 are obtuse */ VCOPY( (srf->v+1), (sub[0].v+0) ); VCOPY( (srf->v+2), (sub[0].v+1) ); VCOPY( (srf->v+3), (sub[0].v+2) ); VCOPY( (srf->v+3), (sub[1].v+0) ); VCOPY( (srf->v+0), (sub[1].v+1) ); VCOPY( (srf->v+1), (sub[1].v+2) ); nSubSrf = 2; break; case 3: /* angles 0 and 1 are obtuse */ tmpVrt.x = 0.5f * (srf->v[2].x + srf->v[3].x ); tmpVrt.y = 0.5f * (srf->v[2].y + srf->v[3].y ); tmpVrt.z = 0.5f * (srf->v[2].z + srf->v[3].z ); VCOPY( (srf->v+3), (sub[0].v+0) ); VCOPY( (srf->v+0), (sub[0].v+1) ); VCOPY( (&tmpVrt), (sub[0].v+2) ); VCOPY( (srf->v+0), (sub[1].v+0) ); VCOPY( (srf->v+1), (sub[1].v+1) ); VCOPY( (&tmpVrt), (sub[1].v+2) ); VCOPY( (srf->v+1), (sub[2].v+0) ); VCOPY( (srf->v+2), (sub[2].v+1) ); VCOPY( (&tmpVrt), (sub[2].v+2) ); nSubSrf = 3; break; case 6: /* angles 1 and 2 are obtuse */ tmpVrt.x = 0.5f * (srf->v[0].x + srf->v[3].x ); tmpVrt.y = 0.5f * (srf->v[0].y + srf->v[3].y ); tmpVrt.z = 0.5f * (srf->v[0].z + srf->v[3].z ); VCOPY( (srf->v+0), (sub[0].v+0) ); VCOPY( (srf->v+1), (sub[0].v+1) ); VCOPY( (&tmpVrt), (sub[0].v+2) ); VCOPY( (srf->v+1), (sub[1].v+0) ); VCOPY( (srf->v+2), (sub[1].v+1) ); VCOPY( (&tmpVrt), (sub[1].v+2) ); VCOPY( (srf->v+2), (sub[2].v+0) ); VCOPY( (srf->v+3), (sub[2].v+1) ); VCOPY( (&tmpVrt), (sub[2].v+2) ); nSubSrf = 3; break; case 9: /* angles 0 and 3 are obtuse */ tmpVrt.x = 0.5f * (srf->v[1].x + srf->v[2].x ); tmpVrt.y = 0.5f * (srf->v[1].y + srf->v[2].y ); tmpVrt.z = 0.5f * (srf->v[1].z + srf->v[2].z ); VCOPY( (srf->v+2), (sub[0].v+0) ); VCOPY( (srf->v+3), (sub[0].v+1) ); VCOPY( (&tmpVrt), (sub[0].v+2) ); VCOPY( (srf->v+3), (sub[1].v+0) ); VCOPY( (srf->v+0), (sub[1].v+1) ); VCOPY( (&tmpVrt), (sub[1].v+2) ); VCOPY( (srf->v+0), (sub[2].v+0) ); VCOPY( (srf->v+1), (sub[2].v+1) ); VCOPY( (&tmpVrt), (sub[2].v+2) ); nSubSrf = 3; break; case 12: /* angles 2 and 3 are obtuse */ tmpVrt.x = 0.5f * (srf->v[0].x + srf->v[1].x ); tmpVrt.y = 0.5f * (srf->v[0].y + srf->v[1].y ); tmpVrt.z = 0.5f * (srf->v[0].z + srf->v[1].z ); VCOPY( (srf->v+1), (sub[0].v+0) ); VCOPY( (srf->v+2), (sub[0].v+1) ); VCOPY( (&tmpVrt), (sub[0].v+2) ); VCOPY( (srf->v+2), (sub[1].v+0) ); VCOPY( (srf->v+3), (sub[1].v+1) ); VCOPY( (&tmpVrt), (sub[1].v+2) ); VCOPY( (srf->v+3), (sub[2].v+0) ); VCOPY( (srf->v+0), (sub[2].v+1) ); VCOPY( (&tmpVrt), (sub[2].v+2) ); nSubSrf = 3; break; case 15: /* invalid configuration */ error( 2, __FILE__, __LINE__, "Invalid configuration", "" ); break; default: error( 2, __FILE__, __LINE__, "Invalid switch: ", IntStr(obtuse), "" ); } /* end switch */ if( obtuse > 0 ) /* complete subdivision data */ for( j=0; j<nSubSrf; j++ ) { sub[j].nr = j; sub[j].nv = 3; SetCentroid( 3, sub[j].v, &sub[j].ctd ); sub[j].area = Triangle( sub[j].v+0, sub[j].v+1, sub[j].v+2, &tmpVrt, 0 ); memcpy( &sub[j].dc, &srf->dc, sizeof(DIRCOS) ); } } else if( srf->nv==5 ) { for( j=0,i=1; j<5; j++,i++ ) { if( i==5 ) i = 0; VCOPY( (&srf->ctd), (sub[j].v+0) ); VCOPY( (srf->v+j), (sub[j].v+1) ); VCOPY( (srf->v+i), (sub[j].v+2) ); sub[j].nr = j; sub[j].nv = 3; SetCentroid( 3, sub[j].v, &sub[j].ctd ); sub[j].area = Triangle( sub[j].v+0, sub[j].v+1, sub[j].v+2, &tmpVrt, 0 ); memcpy( &sub[j].dc, &srf->dc, sizeof(DIRCOS) ); } nSubSrf = 5; } else error( 3, __FILE__, __LINE__, "Invalid number of vertices", IntStr(srf->nv), "" ); return nSubSrf; } /* end Subsurface */