void clip_segment_by_half_plane( Segment2d& S, const vec2& Q1, const vec2& Q2, bool invert ) { if(S.empty) { return ; } Sign P1_status = point_is_in_half_plane( S.p1, Q1, Q2, invert ) ; Sign P2_status = point_is_in_half_plane( S.p2, Q1, Q2, invert ) ; if(P1_status == NEGATIVE && P2_status == NEGATIVE) { S.empty = true ; return ; } if(P1_status != P2_status) { vec2 I ; intersect_segments(S.p1, S.p2, Q1, Q2, I) ; if(P1_status == POSITIVE || P1_status == ZERO) { S.p2 = I ; } else { S.p1 = I ; } } }
void clip_polygon_by_half_plane( const Polygon2d& P, const vec2& q1, const vec2& q2, Polygon2d& result, bool invert ) { result.clear() ; if(P.size() == 0) { return ; } if(P.size() == 1) { if(point_is_in_half_plane(P[0], q1, q2, invert)) { result.push_back(P[0]) ; } return ; } vec2 prev_p = P[P.size() - 1] ; Sign prev_status = point_is_in_half_plane( prev_p, q1, q2, invert ) ; for(unsigned int i=0; i<P.size(); i++) { vec2 p = P[i] ; Sign status = point_is_in_half_plane( p, q1, q2, invert ) ; if( status != prev_status && status != ZERO && prev_status != ZERO ) { vec2 intersect ; if(intersect_segments(prev_p, p, q1, q2, intersect)) { result.push_back(intersect) ; } else { } } switch(status) { case NEGATIVE: break ; case ZERO: result.push_back(p) ; break ; case POSITIVE: result.push_back(p) ; break ; } prev_p = p ; prev_status = status ; } }
inline static uint64_t adios_patch_data_wb_to_wb(void *dst, uint64_t dst_ragged_offset, const ADIOS_SELECTION_WRITEBLOCK_STRUCT *dst_wb, void *src, uint64_t src_ragged_offset, const ADIOS_SELECTION_WRITEBLOCK_STRUCT *src_wb, const ADIOS_SELECTION_BOUNDINGBOX_STRUCT *vb_bounds, enum ADIOS_DATATYPES datum_type, enum ADIOS_FLAG swap_endianness) { uint64_t copy_elem_offset, copy_nelems; const uint64_t vb_size_in_elements = compute_volume(vb_bounds->ndim, vb_bounds->count); const uint64_t dst_elem_offset = dst_wb->is_sub_pg_selection ? dst_wb->element_offset : 0; const uint64_t dst_nelems = dst_wb->is_sub_pg_selection ? dst_wb->nelements : vb_size_in_elements; const uint64_t src_elem_offset = src_wb->is_sub_pg_selection ? src_wb->element_offset : 0; const uint64_t src_nelems = src_wb->is_sub_pg_selection ? src_wb->nelements : vb_size_in_elements; // Find out how many elements overlap between the two // writeblock selections (due to the potential existence // of sub-PG writeblock selections; if both are whole-PG, // this overlap will be complete) int intersects = intersect_segments( dst_elem_offset, dst_nelems, src_elem_offset, src_nelems, ©_elem_offset, ©_nelems ); // Copy any elements that are common to both selections // (for whole-PG writeblock selections, this will be all of them) if (intersects) { int typesize = adios_get_type_size(datum_type, NULL); void *copy_dst = (char*)dst + (copy_elem_offset - dst_elem_offset) * typesize; void *copy_src = (char*)src + (copy_elem_offset - src_elem_offset) * typesize; memcpy(copy_dst, copy_src, copy_nelems * typesize); if (swap_endianness == adios_flag_yes) change_endianness(copy_dst, copy_nelems * typesize, datum_type); return copy_nelems; } else { return 0; } }
// // One-on-one global intersection functions // ADIOS_SELECTION * adios_selection_intersect_wb_wb(const ADIOS_SELECTION_WRITEBLOCK_STRUCT *wb1, const ADIOS_SELECTION_WRITEBLOCK_STRUCT *wb2, int timestep, const ADIOS_VARINFO *raw_varinfo, const ADIOS_TRANSINFO *transinfo) { int is_abs_idx; int wbindex; if (wb1->is_absolute_index == wb2->is_absolute_index) { const int index1 = wb1->index; const int index2 = wb2->index; if (index1 != index2) return NULL; wbindex = index1; is_abs_idx = wb1->is_absolute_index; } else { const int index1 = wb1->is_absolute_index ? wb1->index : adios_get_absolute_writeblock_index(raw_varinfo, wb1->index, timestep); const int index2 = wb2->is_absolute_index ? wb2->index : adios_get_absolute_writeblock_index(raw_varinfo, wb2->index, timestep); if (index1 != index2) return NULL; wbindex = index1; is_abs_idx = 1; } if (!wb1->is_sub_pg_selection && !wb2->is_sub_pg_selection) { // If neither selection is a sub-PG selection, the result is easy, and we can return immediately ADIOS_SELECTION *inter_sel = common_read_selection_writeblock(wbindex); inter_sel->u.block.is_absolute_index = is_abs_idx; return inter_sel; } else if (wb1->is_sub_pg_selection && wb2->is_sub_pg_selection) { // Else, if both selections are sub-PG selections, take the overlapping portion (if any) uint64_t inter_elem_offset, inter_nelems; int intersects = intersect_segments( wb1->element_offset, wb1->nelements, wb2->element_offset, wb2->nelements, &inter_elem_offset, &inter_nelems ); if (intersects) { ADIOS_SELECTION *inter_sel = common_read_selection_writeblock(wbindex); inter_sel->u.block.is_absolute_index = is_abs_idx; inter_sel->u.block.is_sub_pg_selection = 1; inter_sel->u.block.element_offset = inter_elem_offset; inter_sel->u.block.nelements = inter_nelems; return inter_sel; } else { return NULL; } } else if (wb1->is_sub_pg_selection) { // Else, if only the first selection is sub-PG, so just use its range ADIOS_SELECTION *newwb = common_read_selection_writeblock(wb1->index); newwb->u.block = *wb1; return newwb; } else if (wb2->is_sub_pg_selection) { // Else, only the second selection is sub-PG, so just use its range ADIOS_SELECTION *newwb = common_read_selection_writeblock(wb2->index); newwb->u.block = *wb2; return newwb; } else { abort(); // Should not be possible' return NULL; } }