TEUCHOS_UNIT_TEST(tOrientation, testFaceBasis_tet) { out << note << std::endl; // basis to build patterns from RCP<Intrepid2::Basis<PHX::exec_space,double,double> > basisA = rcp(new Intrepid2::Basis_HGRAD_TET_C1_FEM<PHX::exec_space,double,double>); RCP<Intrepid2::Basis<PHX::exec_space,double,double> > basisB = rcp(new Intrepid2::Basis_HDIV_TET_I1_FEM<PHX::exec_space,double,double>); RCP<Intrepid2::Basis<PHX::exec_space,double,double> > basisC = rcp(new Intrepid2::Basis_HGRAD_TET_C2_FEM<PHX::exec_space,double,double>); // used further down RCP<const FieldPattern> patternA = rcp(new Intrepid2FieldPattern(basisA)); RCP<const FieldPattern> patternB = rcp(new Intrepid2FieldPattern(basisB)); RCP<const FieldPattern> patternC = rcp(new Intrepid2FieldPattern(basisC)); // used further down TEST_EQUALITY(patternA->numberIds(),4); TEST_EQUALITY(patternB->numberIds(),4); std::vector<std::vector<int> > topFaceIndices; orientation_helpers::computePatternFaceIndices(*patternA,topFaceIndices); TEST_EQUALITY(topFaceIndices.size(),4); TEST_EQUALITY(topFaceIndices[0].size(),3); TEST_EQUALITY(topFaceIndices[0][0],0); TEST_EQUALITY(topFaceIndices[0][1],1); TEST_EQUALITY(topFaceIndices[0][2],3); TEST_EQUALITY(topFaceIndices[1].size(),3); TEST_EQUALITY(topFaceIndices[1][0],1); TEST_EQUALITY(topFaceIndices[1][1],2); TEST_EQUALITY(topFaceIndices[1][2],3); TEST_EQUALITY(topFaceIndices[2].size(),3); TEST_EQUALITY(topFaceIndices[2][0],0); TEST_EQUALITY(topFaceIndices[2][1],3); TEST_EQUALITY(topFaceIndices[2][2],2); TEST_EQUALITY(topFaceIndices[3].size(),3); TEST_EQUALITY(topFaceIndices[3][0],0); TEST_EQUALITY(topFaceIndices[3][1],2); TEST_EQUALITY(topFaceIndices[3][2],1); // Topologically the first elements look like (shown by looking at each face), note // that the expected orientation is included as a +/- sign in the element // // // 7 7 7 2 // // / \ / \ / \ / \ // // / - \ / - \ / + \ / + \ // // / \ / \ / \ / \ // // 6 ----- 2 2 ----- 9 9 ----- 6 6 ----- 9 // // // // all that matters is the global // node numbering and the local ordering // The local ordering is defined by the following connectivity std::vector<std::vector<long> > connectivity(1); connectivity[0].resize(patternA->numberIds()); connectivity[0][0] = 6; connectivity[0][1] = 2; connectivity[0][2] = 9; connectivity[0][3] = 7; { std::vector<char> orientations(patternB->numberIds(),0); orientation_helpers::computeCellFaceOrientations(topFaceIndices, connectivity[0], *patternB, orientations); TEST_EQUALITY(orientations[0],char(-1)); TEST_EQUALITY(orientations[1],char(-1)); TEST_EQUALITY(orientations[2],char(1)); TEST_EQUALITY(orientations[3],char(1)); } }
void BranchList::calculateOrientations() { for (int i = 0; i < mBranches.size(); i++) { Eigen::MatrixXd positions = mBranches[i]->getPositions(); Eigen::MatrixXd diff = positions.rightCols(positions.cols() - 1) - positions.leftCols(positions.cols() - 1); Eigen::MatrixXd orientations(positions.rows(),positions.cols()); orientations.leftCols(orientations.cols() - 1) = diff / diff.norm(); orientations.rightCols(1) = orientations.col(orientations.cols() - 1); mBranches[i]->setOrientations(orientations); } }
void TestCreateVertexElement() { // Make 8 nodes to assign to a cube element std::vector<Node<3>*> nodes; nodes.push_back(new Node<3>(0, false, 0.0, 0.0, 0.0)); nodes.push_back(new Node<3>(1, false, 1.0, 0.0, 0.0)); nodes.push_back(new Node<3>(2, false, 0.0, 1.0, 0.0)); nodes.push_back(new Node<3>(3, false, 0.0, 0.0, 1.0)); nodes.push_back(new Node<3>(4, false, 1.0, 1.0, 0.0)); nodes.push_back(new Node<3>(5, false, 0.0, 1.0, 1.0)); nodes.push_back(new Node<3>(6, false, 1.0, 0.0, 1.0)); nodes.push_back(new Node<3>(7, false, 1.0, 1.0, 1.0)); std::vector<Node<3>*> nodes_face_0, nodes_face_1, nodes_face_2, nodes_face_3, nodes_face_4, nodes_face_5; // Make 6 square faces out of these nodes nodes_face_0.push_back(nodes[0]); nodes_face_0.push_back(nodes[2]); nodes_face_0.push_back(nodes[4]); nodes_face_0.push_back(nodes[1]); nodes_face_1.push_back(nodes[4]); nodes_face_1.push_back(nodes[7]); nodes_face_1.push_back(nodes[5]); nodes_face_1.push_back(nodes[2]); nodes_face_2.push_back(nodes[7]); nodes_face_2.push_back(nodes[6]); nodes_face_2.push_back(nodes[1]); nodes_face_2.push_back(nodes[4]); nodes_face_3.push_back(nodes[0]); nodes_face_3.push_back(nodes[3]); nodes_face_3.push_back(nodes[5]); nodes_face_3.push_back(nodes[2]); nodes_face_4.push_back(nodes[1]); nodes_face_4.push_back(nodes[6]); nodes_face_4.push_back(nodes[3]); nodes_face_4.push_back(nodes[0]); nodes_face_5.push_back(nodes[7]); nodes_face_5.push_back(nodes[6]); nodes_face_5.push_back(nodes[3]); nodes_face_5.push_back(nodes[5]); std::vector<VertexElement<2,3>*> faces; faces.push_back(new VertexElement<2,3>(0, nodes_face_0)); faces.push_back(new VertexElement<2,3>(1, nodes_face_1)); faces.push_back(new VertexElement<2,3>(2, nodes_face_2)); faces.push_back(new VertexElement<2,3>(3, nodes_face_3)); faces.push_back(new VertexElement<2,3>(4, nodes_face_4)); faces.push_back(new VertexElement<2,3>(5, nodes_face_5)); std::vector<bool> orientations(faces.size()); for (unsigned i=0; i<faces.size(); i++) { orientations[i] = true; } // Make a cube element out of these faces VertexElement<3,3> element(0, faces, orientations); TS_ASSERT_EQUALS(element.GetNumNodes(), 8u); TS_ASSERT_EQUALS(element.GetNumFaces(), 6u); TS_ASSERT_EQUALS(element.GetIndex(), 0u); // Test the position of some random nodes TS_ASSERT_DELTA(element.GetFace(0)->GetNode(0)->rGetLocation()[0], 0.0, 1e-6); TS_ASSERT_DELTA(element.GetFace(0)->GetNode(0)->rGetLocation()[1], 0.0, 1e-6); TS_ASSERT_DELTA(element.GetFace(0)->GetNode(0)->rGetLocation()[2], 0.0, 1e-6); TS_ASSERT_DELTA(element.GetFace(5)->GetNode(2)->rGetLocation()[0], 0.0, 1e-6); TS_ASSERT_DELTA(element.GetFace(5)->GetNode(2)->rGetLocation()[1], 0.0, 1e-6); TS_ASSERT_DELTA(element.GetFace(5)->GetNode(2)->rGetLocation()[2], 1.0, 1e-6); // Test orientations for (unsigned face_index=0; face_index<element.GetNumFaces(); face_index++) { TS_ASSERT_EQUALS(element.FaceIsOrientatedClockwise(face_index), true); } // Tidy up for (unsigned i=0; i<nodes.size(); i++) { delete nodes[i]; } for (unsigned i=0; i<faces.size(); i++) { delete faces[i]; } }
void ofApp::update(){ openNI.update(); if(openNI.isNewFrame()) { ofxOscBundle bundle; int deviceId = openNI.getDeviceID(); int numTrackedUsers = openNI.getNumTrackedUsers(); for(int userIndex = 0; userIndex < numTrackedUsers; userIndex++) { ofxOpenNIUser& user = openNI.getTrackedUser(userIndex); if(user.isTracking() && user.isSkeleton()) { ofxOscMessage msg; msg.setAddress("/ram/skeleton"); int userId = user.getXnID(); string actorName = "OpenNI " + ofToString(userId) + " @" + ofToString(deviceId); int numJoints = user.getNumJoints(); msg.addStringArg(actorName); msg.addIntArg(RAM_JOINT_COUNT); // should use accelerometer to right things // or a custom slider to position people float floorOffset = 0; vector<ofVec3f> positions(JOINT_COUNT); for(int openniIndex = 0; openniIndex < JOINT_COUNT; openniIndex++) { ofxOpenNIJoint& joint = user.getJoint((Joint) openniIndex); positions[openniIndex] = joint.getWorldPosition(); positions[openniIndex].x *= -1; // openni is mirrored left/right if(openniIndex == 0 || positions[openniIndex].y < floorOffset) { floorOffset = positions[openniIndex].y; } } vector<ofQuaternion> orientations(JOINT_COUNT); ofVec3f torsoToNeck = positions[JOINT_NECK] - positions[JOINT_TORSO]; ofVec3f torsoToLeftHip = positions[JOINT_LEFT_HIP] - positions[JOINT_TORSO]; ofVec3f torsoToRightHip = positions[JOINT_RIGHT_HIP] - positions[JOINT_TORSO]; ofVec3f neckToTorso = positions[JOINT_TORSO] - positions[JOINT_NECK]; ofVec3f neckToRightShoulder = positions[JOINT_RIGHT_SHOULDER] - positions[JOINT_NECK]; ofVec3f headToNeck = positions[JOINT_NECK] - positions[JOINT_HEAD]; ofVec3f leftShoulderToLeftElbow = positions[JOINT_LEFT_ELBOW] - positions[JOINT_LEFT_SHOULDER]; ofVec3f leftElbowToLeftHand = positions[JOINT_LEFT_HAND] - positions[JOINT_LEFT_ELBOW]; ofVec3f rightShoulderToRightElbow = positions[JOINT_RIGHT_ELBOW] - positions[JOINT_RIGHT_SHOULDER]; ofVec3f rightElbowToRightHand = positions[JOINT_RIGHT_HAND] - positions[JOINT_RIGHT_ELBOW]; ofVec3f leftHipToLeftKnee = positions[JOINT_LEFT_KNEE] - positions[JOINT_LEFT_HIP]; ofVec3f leftKneeToLeftFoot = positions[JOINT_LEFT_FOOT] - positions[JOINT_LEFT_KNEE]; ofVec3f rightHipToRightKnee = positions[JOINT_RIGHT_KNEE] - positions[JOINT_RIGHT_HIP]; ofVec3f rightKneeToRightFoot = positions[JOINT_RIGHT_FOOT] - positions[JOINT_RIGHT_KNEE]; orientations[JOINT_TORSO] = makeRotate(torsoToNeck, torsoToRightHip); orientations[JOINT_NECK] = makeRotate(neckToTorso, neckToRightShoulder); orientations[JOINT_HEAD] = makeRotate(headToNeck, neckToRightShoulder); orientations[JOINT_LEFT_SHOULDER] = makeRotate(leftShoulderToLeftElbow, neckToRightShoulder); orientations[JOINT_LEFT_ELBOW] = makeRotate(leftElbowToLeftHand, leftShoulderToLeftElbow); orientations[JOINT_LEFT_HAND] = orientations[JOINT_LEFT_ELBOW]; orientations[JOINT_RIGHT_SHOULDER] = makeRotate(rightShoulderToRightElbow, neckToRightShoulder); orientations[JOINT_RIGHT_ELBOW] = makeRotate(rightElbowToRightHand, rightShoulderToRightElbow); orientations[JOINT_RIGHT_HAND] = orientations[JOINT_RIGHT_ELBOW]; orientations[JOINT_LEFT_HIP] = makeRotate(leftHipToLeftKnee, torsoToLeftHip); orientations[JOINT_LEFT_KNEE] = makeRotate(leftKneeToLeftFoot, leftHipToLeftKnee); orientations[JOINT_LEFT_FOOT] = orientations[JOINT_LEFT_KNEE]; orientations[JOINT_RIGHT_HIP] = makeRotate(rightHipToRightKnee, torsoToRightHip); orientations[JOINT_RIGHT_KNEE] = makeRotate(rightKneeToRightFoot, rightHipToRightKnee); orientations[JOINT_RIGHT_FOOT] = orientations[JOINT_RIGHT_KNEE]; for(int ramIndex = 0; ramIndex < RAM_JOINT_COUNT; ramIndex++) { int openniIndex = jointMapping[ramIndex]; ofVec3f position = positions[openniIndex]; // process a copy position -= openniCenter; position.y -= floorOffset; position *= ramScale; msg.addStringArg(ramJointName[ramIndex]); msg.addFloatArg(position.x); msg.addFloatArg(position.y); msg.addFloatArg(position.z); // send zero orientation ofQuaternion& orientation = orientations[openniIndex]; ofVec3f axis; float angle; orientation.getRotate(angle, axis); msg.addFloatArg(angle); msg.addFloatArg(axis.x); msg.addFloatArg(axis.y); msg.addFloatArg(axis.z); } msg.addFloatArg(ofGetElapsedTimef()); bundle.addMessage(msg); } } osc.sendBundle(bundle); } }
TEUCHOS_UNIT_TEST(tOrientation, testEdgeBasis_tri) { out << note << std::endl; // basis to build patterns from RCP<Intrepid2::Basis<PHX::exec_space,double,double> > basisA = rcp(new Intrepid2::Basis_HGRAD_TRI_C1_FEM<PHX::exec_space,double,double>); RCP<Intrepid2::Basis<PHX::exec_space,double,double> > basisB = rcp(new Intrepid2::Basis_HCURL_TRI_I1_FEM<PHX::exec_space,double,double>); RCP<Intrepid2::Basis<PHX::exec_space,double,double> > basisC = rcp(new Intrepid2::Basis_HGRAD_TRI_C2_FEM<PHX::exec_space,double,double>); // used further down RCP<const FieldPattern> patternA = rcp(new Intrepid2FieldPattern(basisA)); RCP<const FieldPattern> patternB = rcp(new Intrepid2FieldPattern(basisB)); RCP<const FieldPattern> patternC = rcp(new Intrepid2FieldPattern(basisC)); // used further down TEST_EQUALITY(patternA->numberIds(),3); TEST_EQUALITY(patternB->numberIds(),3); std::vector<std::pair<int,int> > topEdgeIndices; orientation_helpers::computePatternEdgeIndices(*patternA,topEdgeIndices); TEST_EQUALITY(topEdgeIndices.size(),3); TEST_EQUALITY(topEdgeIndices[0].first,0); TEST_EQUALITY(topEdgeIndices[0].second,1); TEST_EQUALITY(topEdgeIndices[1].first,1); TEST_EQUALITY(topEdgeIndices[1].second,2); TEST_EQUALITY(topEdgeIndices[2].first,2); TEST_EQUALITY(topEdgeIndices[2].second,0); std::vector<std::vector<long> > connectivity(4); connectivity[0].resize(patternA->numberIds()); connectivity[1].resize(patternA->numberIds()); connectivity[2].resize(patternA->numberIds()); connectivity[3].resize(patternA->numberIds()); // Topologocally the four elements look like: // // 3-----1 // |\ /| // | \ / | // | 6 | // | / \ | // |/ \| // 5-----0 // // all that matters is the global // node numbering and the local ordering // The local ordering is defined by the following connectivity connectivity[0][0] = 0; connectivity[0][1] = 6; connectivity[0][2] = 5; connectivity[1][0] = 6; connectivity[1][1] = 0; connectivity[1][2] = 1; connectivity[2][0] = 1; connectivity[2][1] = 3; connectivity[2][2] = 6; connectivity[3][0] = 3; connectivity[3][1] = 5; connectivity[3][2] = 6; // LOCAL element orientations are always set so that they flow in the positive // direction along an edge from node 0 to node 1. As a result if the GID of // node 0 is larger then node 1 then the GLOBAL orientation is -1 (and positive // otherwise. The local definition of the edge direction is defined by // the shards cell topology. { std::vector<char> orientations(patternB->numberIds(),0); orientation_helpers::computeCellEdgeOrientations(topEdgeIndices, connectivity[0], *patternB, orientations); TEST_EQUALITY(orientations[0],char(1)); TEST_EQUALITY(orientations[1],char(-1)); TEST_EQUALITY(orientations[2],char(-1)); } { std::vector<char> orientations(patternB->numberIds(),0); orientation_helpers::computeCellEdgeOrientations(topEdgeIndices, connectivity[1], *patternB, orientations); TEST_EQUALITY(orientations[0],char(-1)); TEST_EQUALITY(orientations[1],char(1)); TEST_EQUALITY(orientations[2],char(1)); } { std::vector<char> orientations(patternB->numberIds(),0); orientation_helpers::computeCellEdgeOrientations(topEdgeIndices, connectivity[2], *patternB, orientations); TEST_EQUALITY(orientations[0],char(1)); TEST_EQUALITY(orientations[1],char(1)); TEST_EQUALITY(orientations[2],char(-1)); } { std::vector<char> orientations(patternB->numberIds(),0); orientation_helpers::computeCellEdgeOrientations(topEdgeIndices, connectivity[3], *patternB, orientations); TEST_EQUALITY(orientations[0],char(1)); TEST_EQUALITY(orientations[1],char(1)); TEST_EQUALITY(orientations[2],char(-1)); } // lets now test an aggregate basis std::vector<std::pair<int,Teuchos::RCP<const FieldPattern> > > patterns; patterns.push_back(std::make_pair(0,patternB)); patterns.push_back(std::make_pair(1,patternC)); patterns.push_back(std::make_pair(2,patternA)); Teuchos::RCP<const FieldPattern> aggPattern = Teuchos::rcp(new FieldAggPattern(patterns)); std::vector<char> orientations(aggPattern->numberIds(),0); orientation_helpers::computeCellEdgeOrientations(topEdgeIndices, connectivity[2], *aggPattern, orientations); int nonzeroCount = 0; for(std::size_t s=0;s<orientations.size();s++) nonzeroCount += orientations[s]*orientations[s]; // should be +1 only if it is an edge TEST_EQUALITY(nonzeroCount,6); // loop over edges char tests[] = { 1,1,-1}; // for element 2 for(std::size_t e=0;e<3;e++) { const std::vector<int> & edgeIndices = aggPattern->getSubcellIndices(1,e); for(std::size_t s=0;s<edgeIndices.size();s++) TEST_EQUALITY(orientations[edgeIndices[s]],tests[e]); } }
TEUCHOS_UNIT_TEST(tOrientation, testFaceBasis_hex) { out << note << std::endl; // basis to build patterns from RCP<Intrepid2::Basis<PHX::exec_space,double,double> > basisA = rcp(new Intrepid2::Basis_HGRAD_HEX_C1_FEM<PHX::exec_space,double,double>); RCP<Intrepid2::Basis<PHX::exec_space,double,double> > basisB = rcp(new Intrepid2::Basis_HDIV_HEX_I1_FEM<PHX::exec_space,double,double>); RCP<Intrepid2::Basis<PHX::exec_space,double,double> > basisC = rcp(new Intrepid2::Basis_HGRAD_HEX_C2_FEM<PHX::exec_space,double,double>); // used further down RCP<const FieldPattern> patternA = rcp(new Intrepid2FieldPattern(basisA)); RCP<const FieldPattern> patternB = rcp(new Intrepid2FieldPattern(basisB)); RCP<const FieldPattern> patternC = rcp(new Intrepid2FieldPattern(basisC)); // used further down TEST_EQUALITY(patternA->numberIds(),8); TEST_EQUALITY(patternB->numberIds(),6); std::vector<std::vector<int> > topFaceIndices; orientation_helpers::computePatternFaceIndices(*patternA,topFaceIndices); // this checks to ensure that each face is oriented in a counter clockwise direction TEST_EQUALITY(topFaceIndices.size(),6); TEST_EQUALITY(topFaceIndices[0].size(),4); TEST_EQUALITY(topFaceIndices[0][0],0); TEST_EQUALITY(topFaceIndices[0][1],1); TEST_EQUALITY(topFaceIndices[0][2],5); TEST_EQUALITY(topFaceIndices[0][3],4); TEST_EQUALITY(topFaceIndices[1].size(),4); TEST_EQUALITY(topFaceIndices[1][0],1); TEST_EQUALITY(topFaceIndices[1][1],2); TEST_EQUALITY(topFaceIndices[1][2],6); TEST_EQUALITY(topFaceIndices[1][3],5); TEST_EQUALITY(topFaceIndices[2].size(),4); TEST_EQUALITY(topFaceIndices[2][0],2); TEST_EQUALITY(topFaceIndices[2][1],3); TEST_EQUALITY(topFaceIndices[2][2],7); TEST_EQUALITY(topFaceIndices[2][3],6); TEST_EQUALITY(topFaceIndices[3].size(),4); TEST_EQUALITY(topFaceIndices[3][0],0); TEST_EQUALITY(topFaceIndices[3][1],4); TEST_EQUALITY(topFaceIndices[3][2],7); TEST_EQUALITY(topFaceIndices[3][3],3); TEST_EQUALITY(topFaceIndices[4].size(),4); TEST_EQUALITY(topFaceIndices[4][0],0); TEST_EQUALITY(topFaceIndices[4][1],3); TEST_EQUALITY(topFaceIndices[4][2],2); TEST_EQUALITY(topFaceIndices[4][3],1); TEST_EQUALITY(topFaceIndices[5].size(),4); TEST_EQUALITY(topFaceIndices[5][0],4); TEST_EQUALITY(topFaceIndices[5][1],5); TEST_EQUALITY(topFaceIndices[5][2],6); TEST_EQUALITY(topFaceIndices[5][3],7); // Topologically the first elements look like (shown by looking at each face), note // that the expected orientation is included as a +/- sign in the element // // 0 ----- 8 8 ----- 9 9 ----- 1 // | | | | | | // | + | | + | | - | // | | | | | | // 5 ----- 2 2 ----- 6 6 ----- 7 // // 1 ----- 0 5 ----- 2 1 ----- 9 // | | | | | | // | + | | + | | - | // | | | | | | // 7 ----- 5 7 ----- 6 0 ----- 8 // // all that matters is the global // node numbering and the local ordering // The local ordering is defined by the following connectivity std::vector<std::vector<long> > connectivity(1); connectivity[0].resize(patternA->numberIds()); connectivity[0][0] = 5; connectivity[0][1] = 2; connectivity[0][2] = 6; connectivity[0][3] = 7; connectivity[0][4] = 0; connectivity[0][5] = 8; connectivity[0][6] = 9; connectivity[0][7] = 1; { std::vector<char> orientations(patternB->numberIds(),0); orientation_helpers::computeCellFaceOrientations(topFaceIndices, connectivity[0], *patternB, orientations); TEST_EQUALITY(orientations[0],char(1)); TEST_EQUALITY(orientations[1],char(1)); TEST_EQUALITY(orientations[2],char(-1)); TEST_EQUALITY(orientations[3],char(1)); TEST_EQUALITY(orientations[4],char(1)); TEST_EQUALITY(orientations[5],char(-1)); } }