static void emit_points(struct brw_clip_compile *c, bool do_offset ) { struct brw_compile *p = &c->func; struct brw_indirect v0 = brw_indirect(0, 0); struct brw_indirect v0ptr = brw_indirect(2, 0); brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist)); brw_DO(p, BRW_EXECUTE_1); { brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0)); brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2)); /* draw if edgeflag != 0 */ brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, deref_1f(v0, brw_varying_to_offset(&c->vue_map, VARYING_SLOT_EDGE)), brw_imm_f(0)); brw_IF(p, BRW_EXECUTE_1); { if (do_offset) apply_one_offset(c, v0); brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE, (_3DPRIM_POINTLIST << URB_WRITE_PRIM_TYPE_SHIFT) | URB_WRITE_PRIM_START | URB_WRITE_PRIM_END); } brw_ENDIF(p); brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); } brw_WHILE(p); }
void brw_clip_init_clipmask( struct brw_clip_compile *c ) { struct brw_compile *p = &c->func; struct brw_reg incoming = get_element_ud(c->reg.R0, 2); /* Shift so that lowest outcode bit is rightmost: */ brw_SHR(p, c->reg.planemask, incoming, brw_imm_ud(26)); if (c->key.nr_userclip) { struct brw_reg tmp = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UD); /* Rearrange userclip outcodes so that they come directly after * the fixed plane bits. */ brw_AND(p, tmp, incoming, brw_imm_ud(0x3f<<14)); brw_SHR(p, tmp, tmp, brw_imm_ud(8)); brw_OR(p, c->reg.planemask, c->reg.planemask, tmp); release_tmp(c, tmp); } }
void TestVector() { SpacePoint vec1(10), vec2, tmp; // DataVector<double> vec1(10),vec2,tmp; vec1 = 5; // (SavableClass&)vec2=(SavableClass&)vec1; vec1[5] = 55; vec2 = vec1 = 10; fcout << vec2 << "\n" << vec1 << "\n"; fcout << "vec1 " << vec1 << "\n vec2 " << vec2 << "\n"; tmp = vec1 + vec2; // DataVector<double> tmp=vec1+vec2; fcout << tmp << "\n"; fcout << "sum " << vec1 + vec2 << " \n min " << vec2 - vec1 << " \n mul " << vec1 * vec2 << "\n"; { FilterTextOut fo("Test1", DataSource::Memory); vec2 = 100; fo << vec2; FilterTextIn fi("Test1", DataSource::Memory); fi >> vec1; } fcout << "vec1" << vec1 << "\n vec2" << vec2 << "\n"; DataVector<SpacePoint> dat(10); dat[0].SetDim(10); dat[0] = 5; for(int k = 1; k < 9; k++) dat[k] = dat[0]; fcout << dat << "\n" << (void *)&vec2 << "\n"; void *tmpv = NULL; FilterTextOut fo("Test1", DataSource::Disk); fo << (void *)&vec1 << 10; //fo<<10; fo.CloseBuf(); FilterTextIn fi("Test1", DataSource::Disk); int tmp_int; //fi>>tmp_int;fcout<<tmp_int; fi >> tmpv >> tmp_int; fcout << tmpv << tmp_int; }
static void test_scans(unsigned int sz) { viennacl::vector<ScalarType> vec1(sz), vec2(sz); std::cout << "Initialize vector..." << std::endl; init_vector(vec1); // INCLUSIVE SCAN std::cout << " --- Inclusive scan ---" << std::endl; std::cout << "Separate vectors: "; viennacl::linalg::inclusive_scan(vec1, vec2); test_scan_values(vec1, vec2, true); std::cout << "In-place: "; vec2 = vec1; viennacl::linalg::inclusive_scan(vec2); test_scan_values(vec1, vec2, true); std::cout << "Inclusive scan tested successfully!" << std::endl << std::endl; std::cout << "Initialize vector..." << std::endl; init_vector(vec1); // EXCLUSIVE SCAN std::cout << " --- Exclusive scan ---" << std::endl; std::cout << "Separate vectors: "; viennacl::linalg::exclusive_scan(vec1, vec2); test_scan_values(vec1, vec2, false); std::cout << "In-place: "; vec2 = vec1; viennacl::linalg::exclusive_scan(vec2); test_scan_values(vec1, vec2, false); std::cout << "Exclusive scan tested successfully!" << std::endl << std::endl; }
static void emit_points(struct brw_clip_compile *c, GLboolean do_offset ) { struct brw_compile *p = &c->func; struct brw_instruction *loop; struct brw_instruction *draw_point; struct brw_indirect v0 = brw_indirect(0, 0); struct brw_indirect v0ptr = brw_indirect(2, 0); brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist)); loop = brw_DO(p, BRW_EXECUTE_1); { brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0)); brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2)); /* draw if edgeflag != 0 */ brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, deref_1f(v0, c->offset[VERT_RESULT_EDGE]), brw_imm_f(0)); draw_point = brw_IF(p, BRW_EXECUTE_1); { if (do_offset) apply_one_offset(c, v0); brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END); } brw_ENDIF(p, draw_point); brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); } brw_WHILE(p, loop); }
void brw_clip_tri_init_vertices( struct brw_clip_compile *c ) { struct brw_compile *p = &c->func; struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */ struct brw_instruction *is_rev; /* Initial list of indices for incoming vertexes: */ brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, tmp0, brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE)); /* XXX: Is there an easier way to do this? Need to reverse every * second tristrip element: Can ignore sometimes? */ is_rev = brw_IF(p, BRW_EXECUTE_1); { brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[1]) ); brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[0]) ); if (c->need_direction) brw_MOV(p, c->reg.dir, brw_imm_f(-1)); } is_rev = brw_ELSE(p, is_rev); { brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[0]) ); brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[1]) ); if (c->need_direction) brw_MOV(p, c->reg.dir, brw_imm_f(1)); } brw_ENDIF(p, is_rev); brw_MOV(p, get_element(c->reg.inlist, 2), brw_address(c->reg.vertex[2]) ); brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0)); brw_MOV(p, c->reg.nr_verts, brw_imm_ud(3)); }
void namevalue_object_t::test<20>() { LLNameValue nValue1(" SecondLife S32 RW SIM 22222"); LLNameValue nValue2(" Virtual S32 RW SIM 33333"); LLNameValue nValue3(" SecondLife S32"); nValue3 = nValue1 % nValue2; ensure_equals("1:operator% failed",*nValue3.getS32(),22222); LLNameValue nValue4(" SecondLife U32 RW SIM 3"); LLNameValue nValue5(" SecondLife S32 RW SIM 2"); LLNameValue nValue6(" SecondLife S32"); nValue6 = nValue4 % nValue5; ensure_equals("2:operator% failed",*nValue6.getS32(),1); LLNameValue nValue10(" SecondLife VEC3 RW SIM <4, 5, 6>"); LLNameValue nValue11(" SecondLife VEC3 RW SIM <1, 2, 3>"); LLNameValue nValue12(" SecondLife VEC3"); LLVector3 vec1(4,5,6); LLVector3 vec2(1,2,3); LLVector3 vec3(vec1 % vec2); nValue12 = nValue10 % nValue11; ensure_equals("5:operator% failed",*nValue12.getVec3(), vec3); }
void namevalue_object_t::test<18>() { LLNameValue nValue1(" SecondLife F32 RW SIM 22222"); LLNameValue nValue2(" SecondLife F32 RW SIM 33333"); LLNameValue nValue3(" SecondLife F32"); nValue3 = nValue1 * nValue2; ensure_equals("1:operator* failed",*nValue3.getF32(),740725926.f); LLNameValue nValue4(" SecondLife S32 RW SIM 22222"); LLNameValue nValue5(" SecondLife F32 RW SIM 33333"); LLNameValue nValue6(" SecondLife F32"); nValue6 = nValue4 * nValue5; ensure_equals("2:operator* failed",*nValue6.getF32(),740725926.f); LLNameValue nValue10(" SecondLife VEC3 RW SIM <2, 2, 2>"); LLNameValue nValue11(" SecondLife VEC3 RW SIM <3, 3, 3>"); LLNameValue nValue12(" SecondLife F32"); LLVector3 vec1(2,2,2); LLVector3 vec2(3,3,3); nValue12 = nValue10 * nValue11; ensure_equals("2:operator* failed",*nValue12.getF32(), (vec1 * vec2)); }
// see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { try { // step 1: parse input std::vector<uint8_t> vec1(data, data + size); json j1 = json::from_cbor(vec1); try { // step 2: round trip std::vector<uint8_t> vec2 = json::to_cbor(j1); // parse serialization json j2 = json::from_cbor(vec2); // serializations must match assert(json::to_cbor(j2) == vec2); } catch (const json::parse_error&) { // parsing a CBOR serialization must not fail assert(false); } } catch (const json::parse_error&) { // parse errors are ok, because input may be random bytes } catch (const json::type_error&) { // type errors can occur during parsing, too } // return 0 - non-zero return values are reserved for future use return 0; }
TEST_F(UUIDTest, test6) { std::list<UUID> vec1(20); const fs::path tmpfile(FileUtils::create_temp_file(FileUtils::temp_path(), "serialization.txt")); ALWAYS_CLEANUP_FILE(tmpfile); { fs::ofstream ofs(tmpfile); boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(vec1); } std::list<UUID> vec2; fs::ifstream ifs(tmpfile); boost::archive::xml_iarchive ia(ifs); ia >> BOOST_SERIALIZATION_NVP(vec2); ASSERT_TRUE(vec1 == vec2); }
void TestVectorManipulation(size_t n) { typedef typename Vector::value_type T; thrust::host_vector<T> src = unittest::random_samples<T>(n); ASSERT_EQUAL(src.size(), n); // basic initialization Vector test0(n); Vector test1(n, (T) 3); ASSERT_EQUAL(test0.size(), n); ASSERT_EQUAL(test1.size(), n); ASSERT_EQUAL((test1 == std::vector<T>(n, (T) 3)), true); // initializing from other vector std::vector<T> stl_vector(src.begin(), src.end()); Vector cpy0 = src; Vector cpy1(stl_vector); Vector cpy2(stl_vector.begin(), stl_vector.end()); ASSERT_EQUAL(cpy0, src); ASSERT_EQUAL(cpy1, src); ASSERT_EQUAL(cpy2, src); // resizing Vector vec1(src); vec1.resize(n + 3); ASSERT_EQUAL(vec1.size(), n + 3); vec1.resize(n); ASSERT_EQUAL(vec1.size(), n); ASSERT_EQUAL(vec1, src); vec1.resize(n + 20, (T) 11); Vector tail(vec1.begin() + n, vec1.end()); ASSERT_EQUAL( (tail == std::vector<T>(20, (T) 11)), true); vec1.resize(0); ASSERT_EQUAL(vec1.size(), 0); ASSERT_EQUAL(vec1.empty(), true); vec1.resize(10); ASSERT_EQUAL(vec1.size(), 10); vec1.clear(); ASSERT_EQUAL(vec1.size(), 0); vec1.resize(5); ASSERT_EQUAL(vec1.size(), 5); // push_back Vector vec2; for(size_t i = 0; i < 10; ++i){ ASSERT_EQUAL(vec2.size(), i); vec2.push_back( (T) i ); ASSERT_EQUAL(vec2.size(), i + 1); for(size_t j = 0; j <= i; j++) ASSERT_EQUAL(vec2[j], j); ASSERT_EQUAL(vec2.back(), i); } // pop_back for(size_t i = 10; i > 0; --i){ ASSERT_EQUAL(vec2.size(), i); ASSERT_EQUAL(vec2.back(), i-1); vec2.pop_back(); ASSERT_EQUAL(vec2.size(), i-1); for(size_t j = 0; j < i; j++) ASSERT_EQUAL(vec2[j], j); } //TODO test swap, erase(pos), erase(begin, end) }
int main() { typedef float ScalarType; // // Initialize OpenCL vectors: // unsigned int vector_size = 10; viennacl::scalar<ScalarType> s = 1.0; //dummy viennacl::vector<ScalarType> vec1(vector_size); viennacl::vector<ScalarType> vec2(vector_size); viennacl::vector<ScalarType> result_mul(vector_size); viennacl::vector<ScalarType> result_div(vector_size); // // fill the operands vec1 and vec2: // for (unsigned int i=0; i<vector_size; ++i) { vec1[i] = static_cast<ScalarType>(i); vec2[i] = static_cast<ScalarType>(vector_size-i); } // // Set up the OpenCL program given in my_compute_kernel: // A program is one compilation unit and can hold many different compute kernels. // viennacl::ocl::program & my_prog = viennacl::ocl::current_context().add_program(my_compute_program, "my_compute_program"); my_prog.add_kernel("elementwise_prod"); //register elementwise product kernel my_prog.add_kernel("elementwise_div"); //register elementwise division kernel // // Now we can get the kernels from the program 'my_program'. // (Note that first all kernels need to be registered via add_kernel() before get_kernel() can be called, // otherwise existing references might be invalidated) // viennacl::ocl::kernel & my_kernel_mul = my_prog.get_kernel("elementwise_prod"); viennacl::ocl::kernel & my_kernel_div = my_prog.get_kernel("elementwise_div"); // // Launch the kernel with 'vector_size' threads in one work group // Note that size_t might differ between host and device. Thus, a cast to cl_uint is necessary for the forth argument. // viennacl::ocl::enqueue(my_kernel_mul(vec1, vec2, result_mul, static_cast<cl_uint>(vec1.size()))); viennacl::ocl::enqueue(my_kernel_div(vec1, vec2, result_div, static_cast<cl_uint>(vec1.size()))); // // Print the result: // std::cout << " vec1: " << vec1 << std::endl; std::cout << " vec2: " << vec2 << std::endl; std::cout << "vec1 .* vec2: " << result_mul << std::endl; std::cout << "vec1 /* vec2: " << result_div << std::endl; std::cout << "norm_2(vec1 .* vec2): " << viennacl::linalg::norm_2(result_mul) << std::endl; std::cout << "norm_2(vec1 /* vec2): " << viennacl::linalg::norm_2(result_div) << std::endl; // // That's it. // std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl; return 0; }
/* Post-fragment-program processing. Send the results to the * framebuffer. * \param arg0 the fragment color * \param arg1 the pass-through depth value * \param arg2 the shader-computed depth value */ void emit_fb_write(struct brw_wm_compile *c, struct brw_reg *arg0, struct brw_reg *arg1, struct brw_reg *arg2, GLuint target, GLuint eot) { struct brw_compile *p = &c->func; struct brw_context *brw = p->brw; struct intel_context *intel = &brw->intel; GLuint nr = 2; GLuint channel; /* Reserve a space for AA - may not be needed: */ if (c->aa_dest_stencil_reg) nr += 1; /* I don't really understand how this achieves the color interleave * (ie RGBARGBA) in the result: [Do the saturation here] */ brw_push_insn_state(p); if (c->key.clamp_fragment_color) brw_set_saturate(p, 1); for (channel = 0; channel < 4; channel++) { if (intel->gen >= 6) { /* gen6 SIMD16 single source DP write looks like: * m + 0: r0 * m + 1: r1 * m + 2: g0 * m + 3: g1 * m + 4: b0 * m + 5: b1 * m + 6: a0 * m + 7: a1 */ if (c->dispatch_width == 16) { brw_MOV(p, brw_message_reg(nr + channel * 2), arg0[channel]); } else { brw_MOV(p, brw_message_reg(nr + channel), arg0[channel]); } } else if (c->dispatch_width == 16 && brw->has_compr4) { /* pre-gen6 SIMD16 single source DP write looks like: * m + 0: r0 * m + 1: g0 * m + 2: b0 * m + 3: a0 * m + 4: r1 * m + 5: g1 * m + 6: b1 * m + 7: a1 * * By setting the high bit of the MRF register number, we indicate * that we want COMPR4 mode - instead of doing the usual destination * + 1 for the second half we get destination + 4. */ brw_MOV(p, brw_message_reg(nr + channel + BRW_MRF_COMPR4), arg0[channel]); } else { /* mov (8) m2.0<1>:ud r28.0<8;8,1>:ud { Align1 } */ /* mov (8) m6.0<1>:ud r29.0<8;8,1>:ud { Align1 SecHalf } */ brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, brw_message_reg(nr + channel), arg0[channel]); if (c->dispatch_width == 16) { brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF); brw_MOV(p, brw_message_reg(nr + channel + 4), sechalf(arg0[channel])); } } } brw_set_saturate(p, 0); /* skip over the regs populated above: */ if (c->dispatch_width == 16) nr += 8; else nr += 4; brw_pop_insn_state(p); if (c->source_depth_to_render_target) { if (c->computes_depth) brw_MOV(p, brw_message_reg(nr), arg2[2]); else brw_MOV(p, brw_message_reg(nr), arg1[1]); /* ? */ nr += 2; } if (c->dest_depth_reg) { GLuint comp = c->dest_depth_reg / 2; GLuint off = c->dest_depth_reg % 2; if (off != 0) { brw_push_insn_state(p); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, brw_message_reg(nr), offset(arg1[comp],1)); /* 2nd half? */ brw_MOV(p, brw_message_reg(nr+1), arg1[comp+1]); brw_pop_insn_state(p); } else { brw_MOV(p, brw_message_reg(nr), arg1[comp]); } nr += 2; } if (intel->gen >= 6) { /* Load the message header. There's no implied move from src0 * to the base mrf on gen6. */ brw_push_insn_state(p); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_MOV(p, retype(brw_message_reg(0), BRW_REGISTER_TYPE_UD), retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD)); brw_pop_insn_state(p); if (target != 0) { brw_MOV(p, retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, 0, 2), BRW_REGISTER_TYPE_UD), brw_imm_ud(target)); } } if (!c->runtime_check_aads_emit) { if (c->aa_dest_stencil_reg) emit_aa(c, arg1, 2); fire_fb_write(c, 0, nr, target, eot); } else { struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); struct brw_reg ip = brw_ip_reg(); struct brw_instruction *jmp; brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_conditionalmod(p, BRW_CONDITIONAL_Z); brw_AND(p, v1_null_ud, get_element_ud(brw_vec8_grf(1,0), 6), brw_imm_ud(1<<26)); jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)); { emit_aa(c, arg1, 2); fire_fb_write(c, 0, nr, target, eot); /* note - thread killed in subroutine */ } brw_land_fwd_jump(p, jmp); /* ELSE: Shuffle up one register to fill in the hole left for AA: */ fire_fb_write(c, 1, nr-1, target, eot); } }
void nuiGLDrawContext::DrawGradient(const nuiGradient& rGradient, const nuiRect& rEnclosingRect, nuiSize x1, nuiSize y1, nuiSize x2, nuiSize y2) { nglVector2f vec(x2 - x1, y2 - y1); nglVector2f para(-vec[1], vec[0]); nglVector2f vec1(vec); nglVector2f para1(para); vec1.Normalize(); para1.Normalize(); // What Quadrant are we in?: // | // a | b // | // ---------------- // | // c | d // | float xa, xb, xc, xd; float ya, yb, yc, yd; float x, y; float xp, yp; float xx, yy; float xxp, yyp; xa = xc = rEnclosingRect.Left(); xb = xd = rEnclosingRect.Right(); ya = yb = rEnclosingRect.Top(); yc = yd = rEnclosingRect.Bottom(); if (x1 < x2) { // Go from a to d or c to b if (y1 == y2) { x = xa; y = ya; xp = xc; yp = yc; xx = xd; yy = yd; xxp= xb; yyp= yb; } else if (y1 < y2) { // a to d IntersectLines(xa,ya, para1[0], para1[1], xb, yb, vec1[0], vec1[1], x, y); IntersectLines(xa,ya, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xp, yp); IntersectLines(xd,yd, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xx, yy); IntersectLines(xd,yd, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xxp, yyp); } else { // c to d IntersectLines(xc,yc, para1[0], para1[1], xa, ya, vec1[0], vec1[1], x, y); IntersectLines(xc,yc, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xp, yp); IntersectLines(xb,yb, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xx, yy); IntersectLines(xb,yb, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xxp, yyp); } } else { if (y1 == y2) { x = xd; y = yd; xp = xb; yp = yb; xx = xa; yy = ya; xxp= xc; yyp= yc; } else if (y1 < y2) { // b to c IntersectLines(xb,yb, para1[0], para1[1], xd, yd, vec1[0], vec1[1], x, y); IntersectLines(xb,yb, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xp, yp); IntersectLines(xc,yc, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xx, yy); IntersectLines(xc,yc, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xxp, yyp); } else { // d to a IntersectLines(xd,yd, para1[0], para1[1], xc, yc, vec1[0], vec1[1], x, y); IntersectLines(xd,yd, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xp, yp); IntersectLines(xa,ya, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xx, yy); IntersectLines(xa,ya, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xxp, yyp); } } float startx,starty; float startxp,startyp; float stopx,stopy; float stopxp,stopyp; if (y1 != y2) { IntersectLines(x1, y1, para1[0], para1[1], x, y, vec1[0], vec1[1], startx, starty); IntersectLines(x1, y1, para1[0], para1[1], xp, yp, vec1[0], vec1[1], startxp, startyp); IntersectLines(x2, y2, para1[0], para1[1], x, y, vec1[0], vec1[1], stopx, stopy); IntersectLines(x2, y2, para1[0], para1[1], xp, yp, vec1[0], vec1[1], stopxp, stopyp); } else { startx = x1; starty = y; startxp = x1; startyp = yp; stopx = x2; stopy = y; stopxp = x2; stopyp = yp; } nuiGradientStopList::const_iterator it = rGradient.GetStopList().begin(); nuiGradientStopList::const_iterator end = rGradient.GetStopList().end(); float px1, py1; float px2, py2; PushClipping(); nuiRect r = rEnclosingRect; nglMatrixf m(GetMatrix()); nglVectorf v1(r.Left(), r.Top(), 0); v1 = m * v1; nglVectorf v2 = nglVectorf(r.Right(), r.Bottom(), 0); v2 = m * v2; r.Set(v1[0], v1[1], v2[0], v2[1], false); Clip(r); SetClipping(true); std::vector<nuiShape::CacheElement::Vertex> vertices; nuiColor col = it->second; vertices.push_back(nuiShape::CacheElement::Vertex(x, y, col)); vertices.push_back(nuiShape::CacheElement::Vertex(xp, yp, col)); for ( ; it != end; ++it) { float r = it->first; float rm = 1.0f - r; px1 = startx * rm + stopx * r; py1 = starty * rm + stopy * r; px2 = startxp * rm + stopxp * r; py2 = startyp * rm + stopyp * r; col = it->second; vertices.push_back(nuiShape::CacheElement::Vertex(px1, py1, col)); vertices.push_back(nuiShape::CacheElement::Vertex(px2, py2, col)); } vertices.push_back(nuiShape::CacheElement::Vertex(xxp, yyp, col)); vertices.push_back(nuiShape::CacheElement::Vertex(xx, yy, col)); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glColorPointer(4, GL_FLOAT, sizeof(nuiShape::CacheElement::Vertex), vertices[0].mColor); glVertexPointer(3, GL_FLOAT, sizeof(nuiShape::CacheElement::Vertex), vertices[0].mCoord); glDrawArrays(GL_QUAD_STRIP, 0, vertices.size()); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); PopClipping(); }
/* Interpolate between two vertices and put the result into a0.0. * Increment a0.0 accordingly. * * Beware that dest_ptr can be equal to v0_ptr! */ void brw_clip_interp_vertex( struct brw_clip_compile *c, struct brw_indirect dest_ptr, struct brw_indirect v0_ptr, /* from */ struct brw_indirect v1_ptr, /* to */ struct brw_reg t0, bool force_edgeflag) { struct brw_codegen *p = &c->func; struct brw_reg t_nopersp, v0_ndc_copy; GLuint slot; /* Just copy the vertex header: */ /* * After CLIP stage, only first 256 bits of the VUE are read * back on Ironlake, so needn't change it */ brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1); /* First handle the 3D and NDC interpolation, in case we * need noperspective interpolation. Doing it early has no * performance impact in any case. */ /* Take a copy of the v0 NDC coordinates, in case dest == v0. */ if (c->has_noperspective_shading) { GLuint offset = brw_varying_to_offset(&c->vue_map, BRW_VARYING_SLOT_NDC); v0_ndc_copy = get_tmp(c); brw_MOV(p, v0_ndc_copy, deref_4f(v0_ptr, offset)); } /* Compute the new 3D position * * dest_hpos = v0_hpos * (1 - t0) + v1_hpos * t0 */ { GLuint delta = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS); struct brw_reg tmp = get_tmp(c); brw_MUL(p, vec4(brw_null_reg()), deref_4f(v1_ptr, delta), t0); brw_MAC(p, tmp, negate(deref_4f(v0_ptr, delta)), t0); brw_ADD(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta), tmp); release_tmp(c, tmp); } /* Recreate the projected (NDC) coordinate in the new vertex header */ brw_clip_project_vertex(c, dest_ptr); /* If we have noperspective attributes, * we need to compute the screen-space t */ if (c->has_noperspective_shading) { GLuint delta = brw_varying_to_offset(&c->vue_map, BRW_VARYING_SLOT_NDC); struct brw_reg tmp = get_tmp(c); t_nopersp = get_tmp(c); /* t_nopersp = vec4(v1.xy, dest.xy) */ brw_MOV(p, t_nopersp, deref_4f(v1_ptr, delta)); brw_MOV(p, tmp, deref_4f(dest_ptr, delta)); brw_set_default_access_mode(p, BRW_ALIGN_16); brw_MOV(p, brw_writemask(t_nopersp, WRITEMASK_ZW), brw_swizzle(tmp, 0, 1, 0, 1)); /* t_nopersp = vec4(v1.xy, dest.xy) - v0.xyxy */ brw_ADD(p, t_nopersp, t_nopersp, negate(brw_swizzle(v0_ndc_copy, 0, 1, 0, 1))); /* Add the absolute values of the X and Y deltas so that if * the points aren't in the same place on the screen we get * nonzero values to divide. * * After that, we have vert1 - vert0 in t_nopersp.x and * vertnew - vert0 in t_nopersp.y * * t_nopersp = vec2(|v1.x -v0.x| + |v1.y -v0.y|, * |dest.x-v0.x| + |dest.y-v0.y|) */ brw_ADD(p, brw_writemask(t_nopersp, WRITEMASK_XY), brw_abs(brw_swizzle(t_nopersp, 0, 2, 0, 0)), brw_abs(brw_swizzle(t_nopersp, 1, 3, 0, 0))); brw_set_default_access_mode(p, BRW_ALIGN_1); /* If the points are in the same place, just substitute a * value to avoid divide-by-zero */ brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, vec1(t_nopersp), brw_imm_f(0)); brw_IF(p, BRW_EXECUTE_1); brw_MOV(p, t_nopersp, brw_imm_vf4(brw_float_to_vf(1.0), brw_float_to_vf(0.0), brw_float_to_vf(0.0), brw_float_to_vf(0.0))); brw_ENDIF(p); /* Now compute t_nopersp = t_nopersp.y/t_nopersp.x and broadcast it. */ brw_math_invert(p, get_element(t_nopersp, 0), get_element(t_nopersp, 0)); brw_MUL(p, vec1(t_nopersp), vec1(t_nopersp), vec1(suboffset(t_nopersp, 1))); brw_set_default_access_mode(p, BRW_ALIGN_16); brw_MOV(p, t_nopersp, brw_swizzle(t_nopersp, 0, 0, 0, 0)); brw_set_default_access_mode(p, BRW_ALIGN_1); release_tmp(c, tmp); release_tmp(c, v0_ndc_copy); } /* Now we can iterate over each attribute * (could be done in pairs?) */ for (slot = 0; slot < c->vue_map.num_slots; slot++) { int varying = c->vue_map.slot_to_varying[slot]; GLuint delta = brw_vue_slot_to_offset(slot); /* HPOS, NDC already handled above */ if (varying == VARYING_SLOT_POS || varying == BRW_VARYING_SLOT_NDC) continue; if (varying == VARYING_SLOT_EDGE) { if (force_edgeflag) brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1)); else brw_MOV(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta)); } else if (varying == VARYING_SLOT_PSIZ) { /* PSIZ doesn't need interpolation because it isn't used by the * fragment shader. */ } else if (varying < VARYING_SLOT_MAX) { /* This is a true vertex result (and not a special value for the VUE * header), so interpolate: * * New = attr0 + t*attr1 - t*attr0 * * Unless the attribute is flat shaded -- in which case just copy * from one of the sources (doesn't matter which; already copied from pv) */ GLuint interp = c->key.interpolation_mode.mode[slot]; if (interp != INTERP_QUALIFIER_FLAT) { struct brw_reg tmp = get_tmp(c); struct brw_reg t = interp == INTERP_QUALIFIER_NOPERSPECTIVE ? t_nopersp : t0; brw_MUL(p, vec4(brw_null_reg()), deref_4f(v1_ptr, delta), t); brw_MAC(p, tmp, negate(deref_4f(v0_ptr, delta)), t); brw_ADD(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta), tmp); release_tmp(c, tmp); } else { brw_MOV(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta)); } } } if (c->vue_map.num_slots % 2) { GLuint delta = brw_vue_slot_to_offset(c->vue_map.num_slots); brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0)); } if (c->has_noperspective_shading) release_tmp(c, t_nopersp); }
/** * Example using STL adaptors */ void STLMoblet::STL_adaptors() { LOG("\n"); LOG("========================= STL adaptors =========================================================================="); LOG("/**"); LOG("* Function object adaptors are used to create a function object from another function object." ); LOG("* The created function object, is not the same as the original functor, but is adapted to a certain need." ); LOG("* For example if we have a function object like std::less, and we want to compare all the elements" ); LOG("* in a range against 10, then be can use an STL adaptor (bind2nd), that bounds the second argument" ); LOG("* of std::less to 10. Then we can use std::less with algorithms like remove_copy_if," ); LOG("* that need a unary predicate." ); LOG("*" ); LOG("* STL provides two functor adaptors: bind1st and bind2nd." ); LOG("*" ); LOG("* bind1st: constructs an unary function object from a binary function object, by binding" ); LOG("* the first argument to a fixed value." ); LOG("*" ); LOG("* bind1st template function is defined like this:" ); LOG("*" ); LOG("* binder1st<SomeFunctor> bind1st (const SomeFunctor& fun, const T& fixedValue" ); LOG("* {" ); LOG("* return binder1st<SomeFunctor>(fun, x);" ); LOG("* }" ); LOG("*" ); LOG("* bind1st returns an binder1st object, which is actually a functor that forwards the function calls" ); LOG("* to the \"fun\" argument it takes as a parameter, when constructed:" ); LOG("*" ); LOG("* template <class Functor> class binder1st {" ); LOG("*" ); LOG("* binder1st(const Functor &fun, Functor::first_argument_type &fixed)" ); LOG("* {" ); LOG("* mFun = fun;" ); LOG("* mFixedValue = fixed;" ); LOG("* }" ); LOG("*" ); LOG("* Functor::result_type operator()(Functor::second_argument_type &someValue){" ); LOG("* return mFun(mFixedValue, someValue);" ); LOG("* }" ); LOG("* };" ); LOG("*" ); LOG("* bind2nd is implemented in a similar way, but instead of binding the first argument," ); LOG("* bind2nd it will bind the second one to a fixed value." ); LOG("*" ); LOG("* bind1st and bind2nd function templates are defined in the <functional> header." ); LOG("*/"); LOG("\n"); LOG(" Example using adaptors "); LOG("\n "); LOG("/**" ); LOG("* bind1st function template: constructs an unary function object from a" ); LOG("* binary function object, by binding the first parameter to a certain value." ); LOG("\n */" ); log_to_console("\n Example using std::bind1st:\n"); int array[] = { 1, -99, 2, -100 }; int arraySize = sizeof(array)/sizeof(array[0]); std::vector<int> vec1(array, array + arraySize); log_to_console(vec1, "vec1 contains: "); LOG("\n" ); LOG("/**std::remove_if calls std::less(0, element). If less(0,element) returns" ); LOG("* true => removes that element." ); LOG("* less(0,element) is equivalent to 0<element." ); LOG("*/" ); LOG("\n" ); TRACE(std::vector<int>::iterator newEnd = std::remove_if(vec1.begin(), vec1.end(), bind1st(std::less<int>(), 1))); log_to_console("vec1 after calling std::remove_if(vec1.begin(), vec1.end(), " "bind1st(std::less<int>(), 0)): "); for(std::vector<int>::iterator it = vec1.begin(); it != newEnd; ++it) { log_to_console(*it); } LOG("\n" ); LOG("/**" ); LOG("* bind2nd function template: constructs an unary function object from a"); LOG("* binary function object, by binding the second parameter to a certain" ); LOG("* value." ); LOG("*/" ); log_to_console("\n Example using std::bind2nd:\n"); std::vector<int> vec2(array, array + arraySize); log_to_console(vec2, "vec2 contains: "); LOG("\n" ); LOG("/** std::remove_if calls std::greater(element, 0)." ); LOG("* If std::greater(element, 0) returns true => removes that element." ); LOG("* std::greater(element, 0) is equivalent to element > 0" ); LOG("*/" ); LOG("\n"); TRACE(newEnd = std::remove_if(vec2.begin(), vec2.end(), bind2nd(std::greater<int>(), 0))); log_to_console("vec2 after calling: std::remove_if(vec2.begin(), vec2.end(), " "bind2nd(std::greater<int>(), 0));"); for(std::vector<int>::iterator it = vec2.begin(); it != newEnd; ++it) { log_to_console(*it); } LOG("\n"); }
void planning_environment::setMarkerShapeFromShape(const shapes::Shape *obj, visualization_msgs::Marker &mk, double padding) { switch (obj->type) { case shapes::SPHERE: mk.type = visualization_msgs::Marker::SPHERE; mk.scale.x = mk.scale.y = mk.scale.z = static_cast<const shapes::Sphere*>(obj)->radius * 2.0 + padding; break; case shapes::BOX: mk.type = visualization_msgs::Marker::CUBE; { const double *size = static_cast<const shapes::Box*>(obj)->size; mk.scale.x = size[0] + padding*2.0; mk.scale.y = size[1] + padding*2.0; mk.scale.z = size[2] + padding*2.0; } break; case shapes::CYLINDER: mk.type = visualization_msgs::Marker::CYLINDER; mk.scale.x = static_cast<const shapes::Cylinder*>(obj)->radius * 2.0 + padding; mk.scale.y = mk.scale.x; mk.scale.z = static_cast<const shapes::Cylinder*>(obj)->length + padding*2.0; break; case shapes::MESH: mk.type = visualization_msgs::Marker::LINE_LIST; mk.scale.x = mk.scale.y = mk.scale.z = 0.001; { const shapes::Mesh *mesh = static_cast<const shapes::Mesh*>(obj); double* vertices = new double[mesh->vertexCount * 3]; double sx = 0.0, sy = 0.0, sz = 0.0; for(unsigned int i = 0; i < mesh->vertexCount; ++i) { unsigned int i3 = i * 3; vertices[i3] = mesh->vertices[i3]; vertices[i3 + 1] = mesh->vertices[i3 + 1]; vertices[i3 + 2] = mesh->vertices[i3 + 2]; sx += vertices[i3]; sy += vertices[i3 + 1]; sz += vertices[i3 + 2]; } // the center of the mesh sx /= (double)mesh->vertexCount; sy /= (double)mesh->vertexCount; sz /= (double)mesh->vertexCount; for (unsigned int i = 0 ; i < mesh->vertexCount ; ++i) { unsigned int i3 = i * 3; // vector from center to the vertex double dx = vertices[i3] - sx; double dy = vertices[i3 + 1] - sy; double dz = vertices[i3 + 2] - sz; // length of vector //double norm = sqrt(dx * dx + dy * dy + dz * dz); double ndx = ((dx > 0) ? dx+padding : dx-padding); double ndy = ((dy > 0) ? dy+padding : dy-padding); double ndz = ((dz > 0) ? dz+padding : dz-padding); // the new distance of the vertex from the center //double fact = scale + padding/norm; vertices[i3] = sx + ndx; //dx * fact; vertices[i3 + 1] = sy + ndy; //dy * fact; vertices[i3 + 2] = sz + ndz; //dz * fact; } tf::Transform trans; tf::poseMsgToTF(mk.pose, trans); for (unsigned int j = 0 ; j < mesh->triangleCount; ++j) { unsigned int t1ind = mesh->triangles[3*j]; unsigned int t2ind = mesh->triangles[3*j + 1]; unsigned int t3ind = mesh->triangles[3*j + 2]; tf::Vector3 vec1(vertices[t1ind*3], vertices[t1ind*3+1], vertices[t1ind*3+2]); tf::Vector3 vec2(vertices[t2ind*3], vertices[t2ind*3+1], vertices[t2ind*3+2]); tf::Vector3 vec3(vertices[t3ind*3], vertices[t3ind*3+1], vertices[t3ind*3+2]); //vec1 = trans*vec1; //vec2 = trans*vec2; //vec3 = trans*vec3; geometry_msgs::Point pt1; pt1.x = vec1.x(); pt1.y = vec1.y(); pt1.z = vec1.z(); geometry_msgs::Point pt2; pt2.x = vec2.x(); pt2.y = vec2.y(); pt2.z = vec2.z(); geometry_msgs::Point pt3; pt3.x = vec3.x(); pt3.y = vec3.y(); pt3.z = vec3.z(); mk.points.push_back(pt1); mk.points.push_back(pt2); mk.points.push_back(pt1); mk.points.push_back(pt3); mk.points.push_back(pt2); mk.points.push_back(pt3); } delete[] vertices; } break; default: ROS_ERROR("Unknown object type: %d", (int)obj->type); } }
/** * Generate the geometry shader program used on Gen6 to perform stream output * (transform feedback). */ void gen6_sol_program(struct brw_gs_compile *c, struct brw_gs_prog_key *key, unsigned num_verts, bool check_edge_flags) { struct brw_compile *p = &c->func; c->prog_data.svbi_postincrement_value = num_verts; brw_gs_alloc_regs(c, num_verts, true); brw_gs_initialize_header(c); if (key->num_transform_feedback_bindings > 0) { unsigned vertex, binding; struct brw_reg destination_indices_uw = vec8(retype(c->reg.destination_indices, BRW_REGISTER_TYPE_UW)); /* Note: since we use the binding table to keep track of buffer offsets * and stride, the GS doesn't need to keep track of a separate pointer * into each buffer; it uses a single pointer which increments by 1 for * each vertex. So we use SVBI0 for this pointer, regardless of whether * transform feedback is in interleaved or separate attribs mode. * * Make sure that the buffers have enough room for all the vertices. */ brw_ADD(p, get_element_ud(c->reg.temp, 0), get_element_ud(c->reg.SVBI, 0), brw_imm_ud(num_verts)); brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, get_element_ud(c->reg.temp, 0), get_element_ud(c->reg.SVBI, 4)); brw_IF(p, BRW_EXECUTE_1); /* Compute the destination indices to write to. Usually we use SVBI[0] * + (0, 1, 2). However, for odd-numbered triangles in tristrips, the * vertices come down the pipeline in reversed winding order, so we need * to flip the order when writing to the transform feedback buffer. To * ensure that flatshading accuracy is preserved, we need to write them * in order SVBI[0] + (0, 2, 1) if we're using the first provoking * vertex convention, and in order SVBI[0] + (1, 0, 2) if we're using * the last provoking vertex convention. * * Note: since brw_imm_v can only be used in instructions in * packed-word execution mode, and SVBI is a double-word, we need to * first move the appropriate immediate constant ((0, 1, 2), (0, 2, 1), * or (1, 0, 2)) to the destination_indices register, and then add SVBI * using a separate instruction. Also, since the immediate constant is * expressed as packed words, and we need to load double-words into * destination_indices, we need to intersperse zeros to fill the upper * halves of each double-word. */ brw_MOV(p, destination_indices_uw, brw_imm_v(0x00020100)); /* (0, 1, 2) */ if (num_verts == 3) { /* Get primitive type into temp register. */ brw_AND(p, get_element_ud(c->reg.temp, 0), get_element_ud(c->reg.R0, 2), brw_imm_ud(0x1f)); /* Test if primitive type is TRISTRIP_REVERSE. We need to do this as * an 8-wide comparison so that the conditional MOV that follows * moves all 8 words correctly. */ brw_CMP(p, vec8(brw_null_reg()), BRW_CONDITIONAL_EQ, get_element_ud(c->reg.temp, 0), brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE)); /* If so, then overwrite destination_indices_uw with the appropriate * reordering. */ brw_MOV(p, destination_indices_uw, brw_imm_v(key->pv_first ? 0x00010200 /* (0, 2, 1) */ : 0x00020001)); /* (1, 0, 2) */ brw_set_predicate_control(p, BRW_PREDICATE_NONE); } brw_ADD(p, c->reg.destination_indices, c->reg.destination_indices, get_element_ud(c->reg.SVBI, 0)); /* For each vertex, generate code to output each varying using the * appropriate binding table entry. */ for (vertex = 0; vertex < num_verts; ++vertex) { /* Set up the correct destination index for this vertex */ brw_MOV(p, get_element_ud(c->reg.header, 5), get_element_ud(c->reg.destination_indices, vertex)); for (binding = 0; binding < key->num_transform_feedback_bindings; ++binding) { unsigned char varying = key->transform_feedback_bindings[binding]; unsigned char slot = c->vue_map.varying_to_slot[varying]; /* From the Sandybridge PRM, Volume 2, Part 1, Section 4.5.1: * * "Prior to End of Thread with a URB_WRITE, the kernel must * ensure that all writes are complete by sending the final * write as a committed write." */ bool final_write = binding == key->num_transform_feedback_bindings - 1 && vertex == num_verts - 1; struct brw_reg vertex_slot = c->reg.vertex[vertex]; vertex_slot.nr += slot / 2; vertex_slot.subnr = (slot % 2) * 16; /* gl_PointSize is stored in VARYING_SLOT_PSIZ.w. */ vertex_slot.dw1.bits.swizzle = varying == VARYING_SLOT_PSIZ ? BRW_SWIZZLE_WWWW : key->transform_feedback_swizzles[binding]; brw_set_access_mode(p, BRW_ALIGN_16); brw_MOV(p, stride(c->reg.header, 4, 4, 1), retype(vertex_slot, BRW_REGISTER_TYPE_UD)); brw_set_access_mode(p, BRW_ALIGN_1); brw_svb_write(p, final_write ? c->reg.temp : brw_null_reg(), /* dest */ 1, /* msg_reg_nr */ c->reg.header, /* src0 */ SURF_INDEX_SOL_BINDING(binding), /* binding_table_index */ final_write); /* send_commit_msg */ } } brw_ENDIF(p); /* Now, reinitialize the header register from R0 to restore the parts of * the register that we overwrote while streaming out transform feedback * data. */ brw_gs_initialize_header(c); /* Finally, wait for the write commit to occur so that we can proceed to * other things safely. * * From the Sandybridge PRM, Volume 4, Part 1, Section 3.3: * * The write commit does not modify the destination register, but * merely clears the dependency associated with the destination * register. Thus, a simple “mov” instruction using the register as a * source is sufficient to wait for the write commit to occur. */ brw_MOV(p, c->reg.temp, c->reg.temp); } brw_gs_ff_sync(c, 1); /* If RASTERIZER_DISCARD is enabled, we have nothing further to do, so * release the URB that was just allocated, and terminate the thread. */ if (key->rasterizer_discard) { brw_gs_terminate(c); return; } brw_gs_overwrite_header_dw2_from_r0(c); switch (num_verts) { case 1: brw_gs_offset_header_dw2(c, URB_WRITE_PRIM_START | URB_WRITE_PRIM_END); brw_gs_emit_vue(c, c->reg.vertex[0], true); break; case 2: brw_gs_offset_header_dw2(c, URB_WRITE_PRIM_START); brw_gs_emit_vue(c, c->reg.vertex[0], false); brw_gs_offset_header_dw2(c, URB_WRITE_PRIM_END - URB_WRITE_PRIM_START); brw_gs_emit_vue(c, c->reg.vertex[1], true); break; case 3: if (check_edge_flags) { /* Only emit vertices 0 and 1 if this is the first triangle of the * polygon. Otherwise they are redundant. */ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_AND(p, retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), get_element_ud(c->reg.R0, 2), brw_imm_ud(BRW_GS_EDGE_INDICATOR_0)); brw_IF(p, BRW_EXECUTE_1); } brw_gs_offset_header_dw2(c, URB_WRITE_PRIM_START); brw_gs_emit_vue(c, c->reg.vertex[0], false); brw_gs_offset_header_dw2(c, -URB_WRITE_PRIM_START); brw_gs_emit_vue(c, c->reg.vertex[1], false); if (check_edge_flags) { brw_ENDIF(p); /* Only emit vertex 2 in PRIM_END mode if this is the last triangle * of the polygon. Otherwise leave the primitive incomplete because * there are more polygon vertices coming. */ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_AND(p, retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), get_element_ud(c->reg.R0, 2), brw_imm_ud(BRW_GS_EDGE_INDICATOR_1)); brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); } brw_gs_offset_header_dw2(c, URB_WRITE_PRIM_END); brw_set_predicate_control(p, BRW_PREDICATE_NONE); brw_gs_emit_vue(c, c->reg.vertex[2], true); break; } }
/* Line clipping, more or less following the following algorithm: * * for (p=0;p<MAX_PLANES;p++) { * if (clipmask & (1 << p)) { * GLfloat dp0 = DOTPROD( vtx0, plane[p] ); * GLfloat dp1 = DOTPROD( vtx1, plane[p] ); * * if (dp1 < 0.0f) { * GLfloat t = dp1 / (dp1 - dp0); * if (t > t1) t1 = t; * } else { * GLfloat t = dp0 / (dp0 - dp1); * if (t > t0) t0 = t; * } * * if (t0 + t1 >= 1.0) * return; * } * } * * interp( ctx, newvtx0, vtx0, vtx1, t0 ); * interp( ctx, newvtx1, vtx1, vtx0, t1 ); * */ static void clip_and_emit_line( struct brw_clip_compile *c ) { struct brw_codegen *p = &c->func; struct brw_indirect vtx0 = brw_indirect(0, 0); struct brw_indirect vtx1 = brw_indirect(1, 0); struct brw_indirect newvtx0 = brw_indirect(2, 0); struct brw_indirect newvtx1 = brw_indirect(3, 0); struct brw_indirect plane_ptr = brw_indirect(4, 0); struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD); GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS); GLint clipdist0_offset = c->key.nr_userclip ? brw_varying_to_offset(&c->vue_map, VARYING_SLOT_CLIP_DIST0) : 0; brw_MOV(p, get_addr_reg(vtx0), brw_address(c->reg.vertex[0])); brw_MOV(p, get_addr_reg(vtx1), brw_address(c->reg.vertex[1])); brw_MOV(p, get_addr_reg(newvtx0), brw_address(c->reg.vertex[2])); brw_MOV(p, get_addr_reg(newvtx1), brw_address(c->reg.vertex[3])); brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c)); /* Note: init t0, t1 together: */ brw_MOV(p, vec2(c->reg.t0), brw_imm_f(0)); brw_clip_init_planes(c); brw_clip_init_clipmask(c); /* -ve rhw workaround */ if (p->devinfo->has_negative_rhw_bug) { brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<20)); brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f)); brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); } /* Set the initial vertex source mask: The first 6 planes are the bounds * of the view volume; the next 8 planes are the user clipping planes. */ brw_MOV(p, c->reg.vertex_src_mask, brw_imm_ud(0x3fc0)); /* Set the initial clipdistance offset to be 6 floats before gl_ClipDistance[0]. * We'll increment 6 times before we start hitting actual user clipping. */ brw_MOV(p, c->reg.clipdistance_offset, brw_imm_d(clipdist0_offset - 6*sizeof(float))); brw_DO(p, BRW_EXECUTE_1); { /* if (planemask & 1) */ brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1)); brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); brw_IF(p, BRW_EXECUTE_1); { brw_AND(p, v1_null_ud, c->reg.vertex_src_mask, brw_imm_ud(1)); brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); brw_IF(p, BRW_EXECUTE_1); { /* user clip distance: just fetch the correct float from each vertex */ struct brw_indirect temp_ptr = brw_indirect(7, 0); brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx0), c->reg.clipdistance_offset); brw_MOV(p, c->reg.dp0, deref_1f(temp_ptr, 0)); brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx1), c->reg.clipdistance_offset); brw_MOV(p, c->reg.dp1, deref_1f(temp_ptr, 0)); } brw_ELSE(p); { /* fixed plane: fetch the hpos, dp4 against the plane. */ if (c->key.nr_userclip) brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0)); else brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0)); brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, hpos_offset), c->reg.plane_equation); brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, hpos_offset), c->reg.plane_equation); } brw_ENDIF(p); brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, vec1(c->reg.dp1), brw_imm_f(0.0f)); brw_IF(p, BRW_EXECUTE_1); { /* * Both can be negative on GM965/G965 due to RHW workaround * if so, this object should be rejected. */ if (p->devinfo->has_negative_rhw_bug) { brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0)); brw_IF(p, BRW_EXECUTE_1); { brw_clip_kill_thread(c); } brw_ENDIF(p); } brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0)); brw_math_invert(p, c->reg.t, c->reg.t); brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1); brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 ); brw_MOV(p, c->reg.t1, c->reg.t); brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); } brw_ELSE(p); { /* Coming back in. We know that both cannot be negative * because the line would have been culled in that case. */ /* If both are positive, do nothing */ /* Only on GM965/G965 */ if (p->devinfo->has_negative_rhw_bug) { brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0)); brw_IF(p, BRW_EXECUTE_1); } { brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1)); brw_math_invert(p, c->reg.t, c->reg.t); brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0); brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 ); brw_MOV(p, c->reg.t0, c->reg.t); brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); } if (p->devinfo->has_negative_rhw_bug) { brw_ENDIF(p); } } brw_ENDIF(p); } brw_ENDIF(p); /* plane_ptr++; */ brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c)); /* while (planemask>>=1) != 0 */ brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1)); brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); brw_SHR(p, c->reg.vertex_src_mask, c->reg.vertex_src_mask, brw_imm_ud(1)); brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); brw_ADD(p, c->reg.clipdistance_offset, c->reg.clipdistance_offset, brw_imm_w(sizeof(float))); brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); } brw_WHILE(p); brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1); brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0)); brw_IF(p, BRW_EXECUTE_1); { brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, false); brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, false); brw_clip_emit_vue(c, newvtx0, BRW_URB_WRITE_ALLOCATE_COMPLETE, (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT) | URB_WRITE_PRIM_START); brw_clip_emit_vue(c, newvtx1, BRW_URB_WRITE_EOT_COMPLETE, (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT) | URB_WRITE_PRIM_END); } brw_ENDIF(p); brw_clip_kill_thread(c); }
void nuiDrawContext::DrawGradient(const nuiGradient& rGradient, const nuiRect& rEnclosingRect, nuiSize x1, nuiSize y1, nuiSize x2, nuiSize y2) { nuiVector2 vec(x2 - x1, y2 - y1); nuiVector2 para(-vec[1], vec[0]); nuiVector2 vec1(vec); nuiVector2 para1(para); vec1.Normalize(); para1.Normalize(); // What Quadrant are we in?: // | // a | b // | // ---------------- // | // c | d // | float xa, xb, xc, xd; float ya, yb, yc, yd; float x, y; float xp, yp; float xx, yy; float xxp, yyp; xa = xc = rEnclosingRect.Left(); xb = xd = rEnclosingRect.Right(); ya = yb = rEnclosingRect.Top(); yc = yd = rEnclosingRect.Bottom(); if (x1 < x2) { // Go from a to d or c to b if (y1 == y2) { x = xa; y = ya; xp = xc; yp = yc; xx = xd; yy = yd; xxp= xb; yyp= yb; } else if (y1 < y2) { // a to d IntersectLines(xa,ya, para1[0], para1[1], xb, yb, vec1[0], vec1[1], x, y); IntersectLines(xa,ya, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xp, yp); IntersectLines(xd,yd, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xx, yy); IntersectLines(xd,yd, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xxp, yyp); } else { // c to d IntersectLines(xc,yc, para1[0], para1[1], xa, ya, vec1[0], vec1[1], x, y); IntersectLines(xc,yc, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xp, yp); IntersectLines(xb,yb, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xx, yy); IntersectLines(xb,yb, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xxp, yyp); } } else { if (y1 == y2) { x = xd; y = yd; xp = xb; yp = yb; xx = xa; yy = ya; xxp= xc; yyp= yc; } else if (y1 < y2) { // b to c IntersectLines(xb,yb, para1[0], para1[1], xd, yd, vec1[0], vec1[1], x, y); IntersectLines(xb,yb, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xp, yp); IntersectLines(xc,yc, para1[0], para1[1], xa, ya, vec1[0], vec1[1], xx, yy); IntersectLines(xc,yc, para1[0], para1[1], xd, yd, vec1[0], vec1[1], xxp, yyp); } else { // d to a IntersectLines(xd,yd, para1[0], para1[1], xc, yc, vec1[0], vec1[1], x, y); IntersectLines(xd,yd, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xp, yp); IntersectLines(xa,ya, para1[0], para1[1], xb, yb, vec1[0], vec1[1], xx, yy); IntersectLines(xa,ya, para1[0], para1[1], xc, yc, vec1[0], vec1[1], xxp, yyp); } } float startx,starty; float startxp,startyp; float stopx,stopy; float stopxp,stopyp; if (y1 != y2) { IntersectLines(x1, y1, para1[0], para1[1], x, y, vec1[0], vec1[1], startx, starty); IntersectLines(x1, y1, para1[0], para1[1], xp, yp, vec1[0], vec1[1], startxp, startyp); IntersectLines(x2, y2, para1[0], para1[1], x, y, vec1[0], vec1[1], stopx, stopy); IntersectLines(x2, y2, para1[0], para1[1], xp, yp, vec1[0], vec1[1], stopxp, stopyp); } else { startx = x1; starty = y; startxp = x1; startyp = yp; stopx = x2; stopy = y; stopxp = x2; stopyp = yp; } nuiGradientStopList::const_iterator it = rGradient.GetStopList().begin(); nuiGradientStopList::const_iterator end = rGradient.GetStopList().end(); float px1, py1; float px2, py2; PushClipping(); Clip(rEnclosingRect); EnableClipping(true); nuiRenderArray* pArray = new nuiRenderArray(GL_TRIANGLE_STRIP); pArray->EnableArray(nuiRenderArray::eVertex); pArray->EnableArray(nuiRenderArray::eColor); // nuiRenderArray Array(GL_LINES); // pArray->SetVertexElements(3); // pArray->SetColorElements(4); nuiColor col = it->second; pArray->SetVertex(x, y); pArray->SetColor(col); pArray->PushVertex(); pArray->SetVertex(xp, yp); pArray->PushVertex(); for ( ; it != end; ++it) { float r = it->first; float rm = 1.0f - r; px1 = startx * rm + stopx * r; py1 = starty * rm + stopy * r; px2 = startxp * rm + stopxp * r; py2 = startyp * rm + stopyp * r; col = it->second; pArray->SetColor(col); pArray->SetVertex(px2, py2); pArray->PushVertex(); pArray->SetVertex(px1, py1); pArray->PushVertex(); } pArray->SetVertex(xx, yy); pArray->PushVertex(); pArray->SetVertex(xxp, yyp); pArray->PushVertex(); DrawArray(pArray); PopClipping(); }
bool MAST::HeatConductionElementBase::internal_residual (bool request_jacobian, RealVectorX& f, RealMatrixX& jac) { const std::vector<Real>& JxW = _fe->get_JxW(); const std::vector<libMesh::Point>& xyz = _fe->get_xyz(); const unsigned int n_phi = _fe->n_shape_functions(), dim = _elem.dim(); RealMatrixX material_mat = RealMatrixX::Zero(dim, dim), dmaterial_mat = RealMatrixX::Zero(dim, dim), // for calculation of Jac when k is temp. dep. mat_n2n2 = RealMatrixX::Zero(n_phi, n_phi); RealVectorX vec1 = RealVectorX::Zero(1), vec2_n2 = RealVectorX::Zero(n_phi), flux = RealVectorX::Zero(dim); std::auto_ptr<MAST::FieldFunction<RealMatrixX> > conductance = _property.thermal_conductance_matrix(*this); libMesh::Point p; std::vector<MAST::FEMOperatorMatrix> dBmat(dim); MAST::FEMOperatorMatrix Bmat; // for calculation of Jac when k is temp. dep. for (unsigned int qp=0; qp<JxW.size(); qp++) { // initialize the Bmat operator for this term _initialize_mass_fem_operator(qp, Bmat); Bmat.right_multiply(vec1, _sol); if (_active_sol_function) dynamic_cast<MAST::MeshFieldFunction<RealVectorX>*> (_active_sol_function)->set_element_quadrature_point_solution(vec1); _local_elem->global_coordinates_location(xyz[qp], p); (*conductance)(p, _time, material_mat); _initialize_flux_fem_operator(qp, dBmat); // calculate the flux for each dimension and add its weighted // component to the residual flux.setZero(); for (unsigned int j=0; j<dim; j++) { dBmat[j].right_multiply(vec1, _sol); // dT_dxj for (unsigned int i=0; i<dim; i++) flux(i) += vec1(0) * material_mat(i,j); // q_i = k_ij dT_dxj } // now add to the residual vector for (unsigned int i=0; i<dim; i++) { vec1(0) = flux(i); dBmat[i].vector_mult_transpose(vec2_n2, vec1); f += JxW[qp] * vec2_n2; } if (request_jacobian) { // Jacobian contribution from int_omega dB_dxi^T k_ij dB_dxj for (unsigned int i=0; i<dim; i++) for (unsigned int j=0; j<dim; j++) { dBmat[i].right_multiply_transpose(mat_n2n2, dBmat[j]); jac += JxW[qp] * material_mat(i,j) * mat_n2n2; } // Jacobian contribution from int_omega dB_dxi dT_dxj dk_ij/dT B if (_active_sol_function) { // get derivative of the conductance matrix wrt temperature conductance->derivative(MAST::PARTIAL_DERIVATIVE, *_active_sol_function, p, _time, dmaterial_mat); for (unsigned int j=0; j<dim; j++) { dBmat[j].right_multiply(vec1, _sol); // dT_dxj for (unsigned int i=0; i<dim; i++) if (dmaterial_mat(i,j) != 0.) { // no need to process for zero terms // dB_dxi^T B dBmat[i].right_multiply_transpose(mat_n2n2, Bmat); // dB_dxi^T (dT_dxj dk_ij/dT) B jac += JxW[qp] * vec1(0) * dmaterial_mat(i,j) * mat_n2n2; } } } } } if (_active_sol_function) dynamic_cast<MAST::MeshFieldFunction<RealVectorX>*> (_active_sol_function)->clear_element_quadrature_point_solution(); return request_jacobian; }
bool MAST::HeatConductionElementBase::velocity_residual (bool request_jacobian, RealVectorX& f, RealMatrixX& jac_xdot, RealMatrixX& jac) { MAST::FEMOperatorMatrix Bmat; const std::vector<Real>& JxW = _fe->get_JxW(); const std::vector<libMesh::Point>& xyz = _fe->get_xyz(); const unsigned int n_phi = _fe->n_shape_functions(), dim = _elem.dim(); RealMatrixX material_mat = RealMatrixX::Zero(dim, dim), mat_n2n2 = RealMatrixX::Zero(n_phi, n_phi); RealVectorX vec1 = RealVectorX::Zero(1), vec2_n2 = RealVectorX::Zero(n_phi); std::auto_ptr<MAST::FieldFunction<RealMatrixX> > capacitance = _property.thermal_capacitance_matrix(*this); libMesh::Point p; for (unsigned int qp=0; qp<JxW.size(); qp++) { _initialize_mass_fem_operator(qp, Bmat); Bmat.right_multiply(vec1, _sol); // B * T if (_active_sol_function) dynamic_cast<MAST::MeshFieldFunction<RealVectorX>*> (_active_sol_function)->set_element_quadrature_point_solution(vec1); _local_elem->global_coordinates_location(xyz[qp], p); (*capacitance)(p, _time, material_mat); Bmat.right_multiply(vec1, _vel); // B * T_dot Bmat.vector_mult_transpose(vec2_n2, vec1); // B^T * B * T_dot f += JxW[qp] * material_mat(0,0) * vec2_n2; // (rho*cp)*JxW B^T B T_dot if (request_jacobian) { Bmat.right_multiply_transpose(mat_n2n2, Bmat); // B^T B jac_xdot += JxW[qp] * material_mat(0,0) * mat_n2n2; // B^T B * JxW (rho*cp) // Jacobian contribution from int_omega B T d(rho*cp)/dT B if (_active_sol_function) { // get derivative of the conductance matrix wrt temperature capacitance->derivative(MAST::PARTIAL_DERIVATIVE, *_active_sol_function, p, _time, material_mat); if (material_mat(0,0) != 0.) { // no need to process for zero terms // B^T (T d(rho cp)/dT) B jac += JxW[qp] * vec1(0) * material_mat(0,0) * mat_n2n2; } } } } if (_active_sol_function) dynamic_cast<MAST::MeshFieldFunction<RealVectorX>*> (_active_sol_function)->clear_element_quadrature_point_solution(); return request_jacobian; }
/*********************************************************************** * Output clipped polygon as an unfilled primitive: */ static void emit_lines(struct brw_clip_compile *c, bool do_offset) { struct brw_compile *p = &c->func; const struct brw_context *brw = p->brw; struct brw_indirect v0 = brw_indirect(0, 0); struct brw_indirect v1 = brw_indirect(1, 0); struct brw_indirect v0ptr = brw_indirect(2, 0); struct brw_indirect v1ptr = brw_indirect(3, 0); /* Need a seperate loop for offset: */ if (do_offset) { brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist)); brw_DO(p, BRW_EXECUTE_1); { brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0)); brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2)); apply_one_offset(c, v0); brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); brw_inst_set_cond_modifier(brw, brw_last_inst, BRW_CONDITIONAL_G); } brw_WHILE(p); brw_inst_set_pred_control(brw, brw_last_inst, BRW_PREDICATE_NORMAL); } /* v1ptr = &inlist[nr_verts] * *v1ptr = v0 */ brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist)); brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v0ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW)); brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v1ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW)); brw_MOV(p, deref_1uw(v1ptr, 0), deref_1uw(v0ptr, 0)); brw_DO(p, BRW_EXECUTE_1); { brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0)); brw_MOV(p, get_addr_reg(v1), deref_1uw(v0ptr, 2)); brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2)); /* draw edge if edgeflag != 0 */ brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, deref_1f(v0, brw_varying_to_offset(&c->vue_map, VARYING_SLOT_EDGE)), brw_imm_f(0)); brw_IF(p, BRW_EXECUTE_1); { brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE, (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT) | URB_WRITE_PRIM_START); brw_clip_emit_vue(c, v1, BRW_URB_WRITE_ALLOCATE_COMPLETE, (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT) | URB_WRITE_PRIM_END); } brw_ENDIF(p); brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); brw_inst_set_cond_modifier(brw, brw_last_inst, BRW_CONDITIONAL_NZ); } brw_WHILE(p); brw_inst_set_pred_control(brw, brw_last_inst, BRW_PREDICATE_NORMAL); }
void vec4_generator::generate_gs_set_channel_masks(struct brw_reg dst, struct brw_reg src) { /* From p21 of volume 4 part 2 of the Ivy Bridge PRM (2.4.3.1 Message * Header: M0.5): * * 15 Vertex 1 DATA [3] / Vertex 0 DATA[7] Channel Mask * * When Swizzle Control = URB_INTERLEAVED this bit controls Vertex 1 * DATA[3], when Swizzle Control = URB_NOSWIZZLE this bit controls * Vertex 0 DATA[7]. This bit is ANDed with the corresponding * channel enable to determine the final channel enable. For the * URB_READ_OWORD & URB_READ_HWORD messages, when final channel * enable is 1 it indicates that Vertex 1 DATA [3] will be included * in the writeback message. For the URB_WRITE_OWORD & * URB_WRITE_HWORD messages, when final channel enable is 1 it * indicates that Vertex 1 DATA [3] will be written to the surface. * * 0: Vertex 1 DATA [3] / Vertex 0 DATA[7] channel not included * 1: Vertex DATA [3] / Vertex 0 DATA[7] channel included * * 14 Vertex 1 DATA [2] Channel Mask * 13 Vertex 1 DATA [1] Channel Mask * 12 Vertex 1 DATA [0] Channel Mask * 11 Vertex 0 DATA [3] Channel Mask * 10 Vertex 0 DATA [2] Channel Mask * 9 Vertex 0 DATA [1] Channel Mask * 8 Vertex 0 DATA [0] Channel Mask * * (This is from a section of the PRM that is agnostic to the particular * type of shader being executed, so "Vertex 0" and "Vertex 1" refer to * geometry shader invocations 0 and 1, respectively). Since we have the * enable flags for geometry shader invocation 0 in bits 3:0 of DWORD 0, * and the enable flags for geometry shader invocation 1 in bits 7:0 of * DWORD 4, we just need to OR them together and store the result in bits * 15:8 of DWORD 5. * * It's easier to get the EU to do this if we think of the src and dst * registers as composed of 32 bytes each; then, we want to pick up the * contents of bytes 0 and 16 from src, OR them together, and store them in * byte 21. * * We can do that by the following EU instruction: * * or(1) dst.21<1>UB src<0,1,0>UB src.16<0,1,0>UB { align1 WE_all } * * Note: this relies on the source register having zeros in (a) bits 7:4 of * DWORD 0 and (b) bits 3:0 of DWORD 4. We can rely on (b) because the * source register was prepared by GS_OPCODE_PREPARE_CHANNEL_MASKS (which * shifts DWORD 4 left by 4 bits), and we can rely on (a) because prior to * the execution of GS_OPCODE_PREPARE_CHANNEL_MASKS, DWORDs 0 and 4 need to * contain valid channel mask values (which are in the range 0x0-0xf). */ dst = retype(dst, BRW_REGISTER_TYPE_UB); src = retype(src, BRW_REGISTER_TYPE_UB); brw_push_insn_state(p); brw_set_access_mode(p, BRW_ALIGN_1); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_OR(p, suboffset(vec1(dst), 21), vec1(src), suboffset(vec1(src), 16)); brw_pop_insn_state(p); }
void BaseVH::filterContoursByEdgeAngle( std::vector< std::vector< cv::Point2f > > &contours , double angleThreshold ) { int numContours = contours.size(); double thresholdVal = - std::cos( ( angleThreshold / 180 ) * CV_PI ); std::vector< std::vector< cv::Point2f > > filteredContours; double averageContourLength = 0; int totalNumEdges = 0; for( int cc = 0; cc < numContours; cc++ ) { int numEdges = contours[ cc ].size(); std::vector< cv::Point2f > filteredContour; int id1 = -1 , id2 = -1 , id3 = -1; for( int ee = 0; ee < numEdges; ee++ ) { cv::Point2f &pt1 = contours[ cc ][ ( ee - 1 + numEdges ) % numEdges ]; cv::Point2f &pt2 = contours[ cc ][ ee ]; tr::Vector2f vec1( pt2.x - pt1.x , pt2.y - pt1.y ); averageContourLength += vec1.norm(); } totalNumEdges += numEdges; } if( totalNumEdges < 4 ) return; averageContourLength /= totalNumEdges; double lengthThreshold = 1e-4 * averageContourLength; for( int cc = 0; cc < numContours; cc++ ) { int numEdges = contours[ cc ].size(); std::vector< cv::Point2f > filteredContour; int id1 = -1 , id2 = -1 , id3 = -1; cv::Point2f prevPoint( 0 , 0 ); for( int ee = 0; ee < numEdges; ee++ ) { cv::Point2f &pt1 = contours[ cc ][ ( ee - 1 + numEdges ) % numEdges ]; cv::Point2f &pt2 = contours[ cc ][ ee ]; cv::Point2f &pt3 = contours[ cc ][ ( ee + 1 ) % numEdges ]; tr::Vector2f vec1( pt2.x - pt1.x , pt2.y - pt1.y ) , vec2( pt3.x - pt2.x , pt3.y - pt2.y ); vec1.normalize(); vec2.normalize(); double val = vec1.dot( vec2 ); if( val < thresholdVal ) { continue; } if( filteredContour.size() > 0 ) { tr::Vector2f vec( prevPoint.x - pt2.x , prevPoint.y - pt2.y ); if( vec.norm() < lengthThreshold ) { continue; } } prevPoint = pt2; filteredContour.push_back( pt2 ); } filteredContours.push_back( filteredContour ); } contours = filteredContours; }
/** * Since no auxiliary routines are needed, we can directly start with main(). **/ int main() { typedef float ScalarType; /** * Initialize OpenCL vectors: **/ unsigned int vector_size = 10; viennacl::vector<ScalarType> vec1(vector_size); viennacl::vector<ScalarType> vec2(vector_size); viennacl::vector<ScalarType> result_mul(vector_size); viennacl::vector<ScalarType> result_div(vector_size); /** * Fill the operands vec1 and vec2 with some numbers. **/ for (unsigned int i=0; i<vector_size; ++i) { vec1[i] = static_cast<ScalarType>(i); vec2[i] = static_cast<ScalarType>(vector_size-i); } /** * Set up the OpenCL program given in my_compute_kernel: * A program is one compilation unit and can hold many different compute kernels. **/ viennacl::ocl::program & my_prog = viennacl::ocl::current_context().add_program(my_compute_program, "my_compute_program"); // Note: Releases older than ViennaCL 1.5.0 required calls to add_kernel(). This is no longer needed, the respective interface has been removed. /** * Now we can get the kernels from the program 'my_program'. * (Note that first all kernels need to be registered via add_kernel() before get_kernel() can be called, * otherwise existing references might be invalidated) **/ viennacl::ocl::kernel & my_kernel_mul = my_prog.get_kernel("elementwise_prod"); viennacl::ocl::kernel & my_kernel_div = my_prog.get_kernel("elementwise_div"); /** * Launch the kernel with 'vector_size' threads in one work group * Note that std::size_t might differ between host and device. Thus, a cast to cl_uint is necessary for the forth argument. **/ viennacl::ocl::enqueue(my_kernel_mul(vec1, vec2, result_mul, static_cast<cl_uint>(vec1.size()))); viennacl::ocl::enqueue(my_kernel_div(vec1, vec2, result_div, static_cast<cl_uint>(vec1.size()))); /** * Print the result: **/ std::cout << " vec1: " << vec1 << std::endl; std::cout << " vec2: " << vec2 << std::endl; std::cout << "vec1 .* vec2: " << result_mul << std::endl; std::cout << "vec1 /* vec2: " << result_div << std::endl; std::cout << "norm_2(vec1 .* vec2): " << viennacl::linalg::norm_2(result_mul) << std::endl; std::cout << "norm_2(vec1 /* vec2): " << viennacl::linalg::norm_2(result_div) << std::endl; /** * We are already done. We only needed a few lines of code by letting ViennaCL deal with the details :-) **/ std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl; return EXIT_SUCCESS; }
/* Use mesa's clipping algorithms, translated to GEN4 assembly. */ void brw_clip_tri( struct brw_clip_compile *c ) { struct brw_compile *p = &c->func; struct brw_indirect vtx = brw_indirect(0, 0); struct brw_indirect vtxPrev = brw_indirect(1, 0); struct brw_indirect vtxOut = brw_indirect(2, 0); struct brw_indirect plane_ptr = brw_indirect(3, 0); struct brw_indirect inlist_ptr = brw_indirect(4, 0); struct brw_indirect outlist_ptr = brw_indirect(5, 0); struct brw_indirect freelist_ptr = brw_indirect(6, 0); struct brw_instruction *plane_loop; struct brw_instruction *plane_active; struct brw_instruction *vertex_loop; struct brw_instruction *next_test; struct brw_instruction *prev_test; brw_MOV(p, get_addr_reg(vtxPrev), brw_address(c->reg.vertex[2]) ); brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c)); brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist)); brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist)); brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) ); plane_loop = brw_DO(p, BRW_EXECUTE_1); { /* if (planemask & 1) */ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1)); plane_active = brw_IF(p, BRW_EXECUTE_1); { /* vtxOut = freelist_ptr++ */ brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(freelist_ptr) ); brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE)); if (c->key.nr_userclip) brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0)); else brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0)); brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0)); vertex_loop = brw_DO(p, BRW_EXECUTE_1); { /* vtx = *input_ptr; */ brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0)); /* IS_NEGATIVE(prev) */ brw_set_conditionalmod(p, BRW_CONDITIONAL_L); brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, c->offset_hpos), c->reg.plane_equation); prev_test = brw_IF(p, BRW_EXECUTE_1); { /* IS_POSITIVE(next) */ brw_set_conditionalmod(p, BRW_CONDITIONAL_GE); brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset_hpos), c->reg.plane_equation); next_test = brw_IF(p, BRW_EXECUTE_1); { /* Coming back in. */ brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp)); brw_math_invert(p, c->reg.t, c->reg.t); brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev); /* If (vtxOut == 0) vtxOut = vtxPrev */ brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) ); brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev) ); brw_set_predicate_control(p, BRW_PREDICATE_NONE); brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, GL_FALSE); /* *outlist_ptr++ = vtxOut; * nr_verts++; * vtxOut = 0; */ brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut)); brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short))); brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1)); brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) ); } brw_ENDIF(p, next_test); } prev_test = brw_ELSE(p, prev_test); { /* *outlist_ptr++ = vtxPrev; * nr_verts++; */ brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev)); brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short))); brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1)); /* IS_NEGATIVE(next) */ brw_set_conditionalmod(p, BRW_CONDITIONAL_L); brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset_hpos), c->reg.plane_equation); next_test = brw_IF(p, BRW_EXECUTE_1); { /* Going out of bounds. Avoid division by zero as we * know dp != dpPrev from DIFFERENT_SIGNS, above. */ brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev)); brw_math_invert(p, c->reg.t, c->reg.t); brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp); /* If (vtxOut == 0) vtxOut = vtx */ brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) ); brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx) ); brw_set_predicate_control(p, BRW_PREDICATE_NONE); brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, GL_TRUE); /* *outlist_ptr++ = vtxOut; * nr_verts++; * vtxOut = 0; */ brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut)); brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short))); brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1)); brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) ); } brw_ENDIF(p, next_test); } brw_ENDIF(p, prev_test); /* vtxPrev = vtx; * inlist_ptr++; */ brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx)); brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short))); /* while (--loopcount != 0) */ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); } brw_WHILE(p, vertex_loop); /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1] * inlist = outlist * inlist_ptr = &inlist[0] * outlist_ptr = &outlist[0] */ brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2)); brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0)); brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0)); brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist)); brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist)); } brw_ENDIF(p, plane_active); /* plane_ptr++; */ brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c)); /* nr_verts >= 3 */ brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_GE, c->reg.nr_verts, brw_imm_ud(3)); /* && (planemask>>=1) != 0 */ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1)); } brw_WHILE(p, plane_loop); }
Matrix<double> BspCurvBasisFuncSet::CreateMatrixIntegral(int lev, double x1, double x2) const { KnotSet kset = KnotSet(*kts,ord,num).CreateKnotSetDeriv(lev); Matrix<double> mat(kset.GetNum()-(ord-lev),kset.GetNum()-(ord-lev)); BspCurvBasisFuncSet basis(kset.GetKnots(),ord-lev,kset.GetNum()); // find the first basis function for which the last distinct // knot is greater than x1 int ind1=-1; do { ind1++; } while ((*(basis.b))[ind1].GetKnots()[ord-lev] <= x1); // find the last basis function for which the first distinct // knot is less than x2 int ind2=-1; do { ind2++; } while (ind2 < kset.GetNum()-ord+lev && (*(basis.b))[ind2].GetKnots()[0] < x2); Matrix<double> mat1(kset.GetNum()-ord+lev,kset.GetNum()-ord+lev,0.0); for (int i=ind1; i<=ind2-1; i++) for (int j=ind1; j<=i; j++) { // create the two std::sets representing the two knot std::sets Vector<double> temp1((*(basis.b))[i].GetKnots()); Vector<double> temp2((*(basis.b))[j].GetKnots()); std::set<double> s1(temp1.begin(),temp1.end()); std::set<double> s2(temp2.begin(),temp2.end()); if (*(--s2.end()) > *(s1.begin())) { // form the intersection std::set<double> s3; std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::inserter(s3,s3.begin())); // if there is an intersection if (s3.size() > 1) { Vector<double> v(s3.size()); std::set<double>::iterator s = s3.begin(); // copy the elements into a vector for (unsigned int k=0; k<s3.size(); k++) v[k] = *s++; // create the compbezcurvs Vector<BezCurv<double> > vec1(s3.size()-1); Vector<BezCurv<double> > vec2(s3.size()-1); BspCurv<double> b1((*(basis.b))[i].GetBspCurv()), b2((*(basis.b))[j].GetBspCurv()); // find the segments of intersection for (unsigned int k=0; k<s3.size()-1; k++) { int segb1 = b1.GetKnotSet().Find_segment(v[k]); int segb2 = b2.GetKnotSet().Find_segment(v[k]); vec1[k] = b1.GetSegment(segb1); vec2[k] = b2.GetSegment(segb2); } CompBezCurv<double> cb1(vec1,s3.size()-1,v); CompBezCurv<double> cb2(vec2,s3.size()-1,v); CompBezCurv<double> prod = cb1.Product(cb2); mat1[i][j] = prod.ConvertBspCurv().Integrate(x1,x2); } } } for (int i=ind1; i<=ind2-2; i++) for (int j=i+1; j<=ind2-1; j++) mat1[i][j] = mat1[j][i]; return mat1; }
void Ellipsoid::subDraw() { computeAssistVar(); getPrimitiveSetList().clear(); osg::ref_ptr<osg::Vec3Array> vertexArr = new osg::Vec3Array; osg::ref_ptr<osg::Vec3Array> normalArr = new osg::Vec3Array; setVertexArray(vertexArr); setNormalArray(normalArr, osg::Array::BIND_PER_VERTEX); osg::ref_ptr<osg::Vec4Array> colArr = new osg::Vec4Array(); colArr->push_back(m_color); setColorArray(colArr, osg::Array::BIND_OVERALL); bool isFull = osg::equivalent(m_angle, 2 * M_PI, GetEpsilon()); if (isFull) { m_angle = 2 * M_PI; } osg::Vec3 bottomNormal = -m_aLen; bottomNormal.normalize(); osg::Quat localToWold; localToWold.makeRotate(osg::Z_AXIS, -bottomNormal); osg::Vec3 xVec = localToWold * osg::X_AXIS; osg::Vec3 yVec = xVec ^ bottomNormal; int hCount = m_bDivision; double hIncAng = 2 * M_PI / hCount; osg::Quat hQuat(hIncAng, bottomNormal); int vCount = (int)ceil(m_angle / (2 * M_PI / m_aDivision)); if (vCount & 1) // 如果是奇数,则变成偶数 ++vCount; double vIncAng = m_angle / vCount; double currAngle = m_angle / 2.0; double b = m_bRadius; double a = m_aLen.length(); osg::Vec3 vec1(b * sin(currAngle), 0, a * cos(currAngle)); vec1 = localToWold * vec1; osg::Vec3 normal1(sin(currAngle) / b, 0, cos(currAngle) / a); normal1 = localToWold * normal1; normal1.normalize(); currAngle -= vIncAng; osg::Vec3 vec2(b * sin(currAngle), 0, a * cos(currAngle)); vec2 = localToWold * vec2; osg::Vec3 normal2(sin(currAngle) / b, 0, cos(currAngle) / a); normal2 = localToWold * normal2; normal2.normalize(); const GLint first = vertexArr->size(); for (int i = 0; i < vCount / 2; ++i) { osg::Vec3 hVec1 = vec1; osg::Vec3 hVec2 = vec2; osg::Vec3 hNormal1 = normal1; osg::Vec3 hNormal2 = normal2; const size_t hFirst = vertexArr->size(); for (int j = 0; j < hCount; ++j) { vertexArr->push_back(m_center + hVec1); vertexArr->push_back(m_center + hVec2); normalArr->push_back(hNormal1); normalArr->push_back(hNormal2); hVec1 = hQuat * hVec1; hVec2 = hQuat * hVec2; hNormal1 = hQuat * hNormal1; hNormal2 = hQuat * hNormal2; } vertexArr->push_back((*vertexArr)[hFirst]); vertexArr->push_back((*vertexArr)[hFirst + 1]); normalArr->push_back((*normalArr)[hFirst]); normalArr->push_back((*normalArr)[hFirst + 1]); vec1 = vec2; currAngle -= vIncAng; vec2.set(b * sin(currAngle), 0, a * cos(currAngle)); vec2 = localToWold * vec2; normal1 = normal2; normal2.set(sin(currAngle) / b, 0, cos(currAngle) / a); normal2 = localToWold * normal2; normal2.normalize(); } addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP, first, vertexArr->size() - first)); if (!isFull && m_bottomVis) { const GLint first = vertexArr->size(); currAngle = m_angle / 2.0; osg::Vec3 vec1(b * sin(currAngle), 0, a * cos(currAngle)); vec1 = localToWold * vec1; osg::Vec3 vec2(0, 0, a * cos(currAngle)); vec2 = localToWold * vec2; vertexArr->push_back(m_center + vec2); normalArr->push_back(bottomNormal); for (int i = 0; i < hCount; ++i) { vertexArr->push_back(m_center + vec1); normalArr->push_back(bottomNormal); vec1 = hQuat * vec1; } vertexArr->push_back((*vertexArr)[first + 1]); normalArr->push_back(bottomNormal); addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, first, vertexArr->size() - first)); } }
Matrix<double> BspCurvBasisFuncSet::CreateMatrixIntegral(int lev1, int lev2) const { KnotSet kset1 = KnotSet(*kts,ord,num).CreateKnotSetDeriv(lev1); KnotSet kset2 = KnotSet(*kts,ord,num).CreateKnotSetDeriv(lev2); Matrix<double> mat(kset1.GetNum()-(ord-lev1),kset2.GetNum()-(ord-lev2)); BspCurvBasisFuncSet basis1(kset1.GetKnots(),ord-lev1,kset1.GetNum()); BspCurvBasisFuncSet basis2(kset2.GetKnots(),ord-lev2,kset2.GetNum()); // find the first basis function for which the last distinct // knot is greater than x1 Matrix<double> mat1(kset1.GetNum()-ord+lev1,kset2.GetNum()-ord+lev2,0.0); for (int i=0; i<kset1.GetNum()-ord+lev1; i++) for (int j=0; j<kset2.GetNum()-ord+lev2; j++) { // create the two std::sets representing the two knot std::sets Vector<double> temp1((*(basis1.b))[i].GetKnots()); Vector<double> temp2((*(basis2.b))[j].GetKnots()); std::set<double> s1(temp1.begin(),temp1.end()); std::set<double> s2(temp2.begin(),temp2.end()); if (*(--s2.end()) > *(s1.begin())) { // form the intersection std::set<double> s3; std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::inserter(s3,s3.begin())); // if there is an intersection if (s3.size() > 1) { Vector<double> v(s3.size()); std::set<double>::iterator s = s3.begin(); // copy the elements into a vector for (unsigned int k=0; k<s3.size(); k++) v[k] = *s++; // create the compbezcurvs Vector<BezCurv<double> > vec1(s3.size()-1); Vector<BezCurv<double> > vec2(s3.size()-1); BspCurv<double> b1((*(basis1.b))[i].GetBspCurv()), b2((*(basis2.b))[j].GetBspCurv()); // find the segments of intersection for (unsigned int k=0; k<s3.size()-1; k++) { int segb1 = b1.GetKnotSet().Find_segment(v[k]); int segb2 = b2.GetKnotSet().Find_segment(v[k]); vec1[k] = b1.GetSegment(segb1); vec2[k] = b2.GetSegment(segb2); } CompBezCurv<double> cb1(vec1,s3.size()-1,v); CompBezCurv<double> cb2(vec2,s3.size()-1,v); CompBezCurv<double> prod = cb1.Product(cb2); mat1[i][j] = prod.ConvertBspCurv().Integrate((*kts)[ord-1],(*kts)[num-ord]); } } } return mat1; }