void TestRef::nondefault_ctor() { SimpleEDProductGetter getter; edm::ProductID id(1, 201U); CPPUNIT_ASSERT(id.isValid()); auto prod = std::make_unique<product1_t>(); prod->push_back(1); prod->push_back(2); getter.addProduct(id, std::move(prod)); ref1_t ref0(id, 0, &getter); CPPUNIT_ASSERT(ref0.isNull()==false); CPPUNIT_ASSERT(ref0.isNonnull()); CPPUNIT_ASSERT(!!ref0); CPPUNIT_ASSERT(ref0.productGetter()==&getter); CPPUNIT_ASSERT(ref0.id().isValid()); CPPUNIT_ASSERT(ref0.isAvailable()==true); CPPUNIT_ASSERT(*ref0 == 1); ref1_t ref1(id, 1, &getter); CPPUNIT_ASSERT(ref1.isNonnull()); CPPUNIT_ASSERT(ref1.isAvailable()==true); CPPUNIT_ASSERT(*ref1 == 2); // Note that nothing stops one from making an edm::Ref into a // collection using an index that is invalid. So there is no testing // of such use to be done. }
void TestRef::threading() { SimpleEDProductGetter getter; edm::ProductID id(1, 1U); CPPUNIT_ASSERT(id.isValid()); auto prod = std::make_unique<product1_t>(); prod->push_back(1); prod->push_back(2); getter.addProduct(id, std::move(prod)); ref1_t ref0(id, 0, &getter); ref1_t ref1(id, 1, &getter); std::vector<std::thread> threads; std::vector<std::exception_ptr> excepPtrs(kNThreads,std::exception_ptr{}); for(unsigned int i=0; i< kNThreads; ++i) { threads.emplace_back([&ref0,&ref1,i,&excepPtrs]() { --s_threadsStarting; while(0 != s_threadsStarting) {} try{ CPPUNIT_ASSERT(*ref0 == 1); CPPUNIT_ASSERT(*ref1 == 2); } catch(...) { excepPtrs[i]=std::current_exception(); } }); } for( auto& t: threads) { t.join(); } for(auto& e: excepPtrs) { if(e) { std::rethrow_exception(e); } } }
void TestRefVector::testIteration() { typedef std::vector<double> product_t; typedef edm::Ref<product_t> ref_t; typedef edm::RefVector<product_t> refvec_t; product_t product; product.push_back(1.0); product.push_back(0.5); product.push_back(2.0); refvec_t refvec; CPPUNIT_ASSERT(refvec.size() == 0); CPPUNIT_ASSERT(refvec.empty()); ref_t ref0(edm::ProductID(1, 1), &product[0], 0, &product); refvec.push_back(ref0); ref_t ref1(edm::ProductID(1, 1), &product[1], 1, &product); refvec.push_back(ref1); ref_t ref2(edm::ProductID(1, 1), &product[2], 2, &product); refvec.push_back(ref2); auto iter = refvec.begin(); CPPUNIT_ASSERT(iter->id() == edm::ProductID(1,1) && iter->key() == 0 && *(iter->get()) == 1.0); ++iter; CPPUNIT_ASSERT(iter->id() == edm::ProductID(1,1) && iter->key() == 1 && *(iter->get()) == 0.5); ++iter; CPPUNIT_ASSERT(iter->id() == edm::ProductID(1,1) && iter->key() == 2 && *(iter->get()) == 2.0); ++iter; CPPUNIT_ASSERT(iter == refvec.end()); }
IGL_INLINE void igl::PolyVectorFieldFinder<DerivedV, DerivedF>::computek() { K.setZero(numE); // For every non-border edge for (unsigned eid=0; eid<numE; ++eid) { if (!isBorderEdge[eid]) { int fid0 = E2F(eid,0); int fid1 = E2F(eid,1); Eigen::Matrix<typename DerivedV::Scalar, 1, 3> N0 = FN.row(fid0); Eigen::Matrix<typename DerivedV::Scalar, 1, 3> N1 = FN.row(fid1); // find common edge on triangle 0 and 1 int fid0_vc = -1; int fid1_vc = -1; for (unsigned i=0;i<3;++i) { if (F2E(fid0,i) == eid) fid0_vc = i; if (F2E(fid1,i) == eid) fid1_vc = i; } assert(fid0_vc != -1); assert(fid1_vc != -1); Eigen::Matrix<typename DerivedV::Scalar, 1, 3> common_edge = V.row(F(fid0,(fid0_vc+1)%3)) - V.row(F(fid0,fid0_vc)); common_edge.normalize(); // Map the two triangles in a new space where the common edge is the x axis and the N0 the z axis Eigen::Matrix<typename DerivedV::Scalar, 3, 3> P; Eigen::Matrix<typename DerivedV::Scalar, 1, 3> o = V.row(F(fid0,fid0_vc)); Eigen::Matrix<typename DerivedV::Scalar, 1, 3> tmp = -N0.cross(common_edge); P << common_edge, tmp, N0; // P.transposeInPlace(); Eigen::Matrix<typename DerivedV::Scalar, 3, 3> V0; V0.row(0) = V.row(F(fid0,0)) -o; V0.row(1) = V.row(F(fid0,1)) -o; V0.row(2) = V.row(F(fid0,2)) -o; V0 = (P*V0.transpose()).transpose(); // assert(V0(0,2) < 1e-10); // assert(V0(1,2) < 1e-10); // assert(V0(2,2) < 1e-10); Eigen::Matrix<typename DerivedV::Scalar, 3, 3> V1; V1.row(0) = V.row(F(fid1,0)) -o; V1.row(1) = V.row(F(fid1,1)) -o; V1.row(2) = V.row(F(fid1,2)) -o; V1 = (P*V1.transpose()).transpose(); // assert(V1(fid1_vc,2) < 10e-10); // assert(V1((fid1_vc+1)%3,2) < 10e-10); // compute rotation R such that R * N1 = N0 // i.e. map both triangles to the same plane double alpha = -atan2(V1((fid1_vc+2)%3,2),V1((fid1_vc+2)%3,1)); Eigen::Matrix<typename DerivedV::Scalar, 3, 3> R; R << 1, 0, 0, 0, cos(alpha), -sin(alpha) , 0, sin(alpha), cos(alpha); V1 = (R*V1.transpose()).transpose(); // assert(V1(0,2) < 1e-10); // assert(V1(1,2) < 1e-10); // assert(V1(2,2) < 1e-10); // measure the angle between the reference frames // k_ij is the angle between the triangle on the left and the one on the right Eigen::Matrix<typename DerivedV::Scalar, 1, 3> ref0 = V0.row(1) - V0.row(0); Eigen::Matrix<typename DerivedV::Scalar, 1, 3> ref1 = V1.row(1) - V1.row(0); ref0.normalize(); ref1.normalize(); double ktemp = atan2(ref1(1),ref1(0)) - atan2(ref0(1),ref0(0)); // just to be sure, rotate ref0 using angle ktemp... Eigen::Matrix<typename DerivedV::Scalar, 2, 2> R2; R2 << cos(ktemp), -sin(ktemp), sin(ktemp), cos(ktemp); Eigen::Matrix<typename DerivedV::Scalar, 1, 2> tmp1 = R2*(ref0.head(2)).transpose(); // assert(tmp1(0) - ref1(0) < 1e-10); // assert(tmp1(1) - ref1(1) < 1e-10); K[eid] = ktemp; } } }