HexahedralMeshIterators.cc 9.66 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
/*===========================================================================*\
 *                                                                           *
 *                            OpenVolumeMesh                                 *
 *        Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen         *
 *                        www.openvolumemesh.org                             *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenVolumeMesh.                                     *
 *                                                                           *
 *  OpenVolumeMesh is free software: you can redistribute it and/or modify   *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenVolumeMesh is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenVolumeMesh.  If not,                              *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
 *   $Revision$                                                         *
 *   $Date$                    *
 *   $LastChangedBy$                                                *
 *                                                                           *
\*===========================================================================*/

#include <set>

#include "HexahedralMeshIterators.hh"
#include "HexahedralMeshTopologyKernel.hh"
#include "../Core/Iterators.hh"

namespace OpenVolumeMesh {

//================================================================================================
// CellSheetCellIter
//================================================================================================

55 56 57

CellSheetCellIter::CellSheetCellIter(const CellHandle& _ref_h,
        const unsigned char _orthDir, const HexahedralMeshTopologyKernel* _mesh) :
58 59
BaseIter(_mesh, _ref_h) {

60
    if(!_mesh->has_face_bottom_up_adjacencies()) {
61 62 63 64 65 66 67
        std::cerr << "This iterator needs bottom-up adjacencies!" << std::endl;
        BaseIter::valid(false);
        return;
    }

	// First off, get all surrounding cells
	std::vector<HalfFaceHandle> halffaces = _mesh->cell(_ref_h).halffaces();
68
	for(std::vector<HalfFaceHandle>::const_iterator hf_it = halffaces.begin();
69 70 71 72 73
			hf_it != halffaces.end(); ++hf_it) {
		// Add those, that are perpendicular to the specified _orthDir
		if(_mesh->orientation(*hf_it, _ref_h) != _orthDir &&
				_mesh->orientation(*hf_it, _ref_h) != _mesh->opposite_orientation(_orthDir)) {
			CellHandle ch = _mesh->incident_cell(_mesh->opposite_halfface_handle(*hf_it));
74
			if(ch != TopologyKernel::InvalidCellHandle) {
75 76 77 78 79 80 81 82 83 84 85 86
				neighb_sheet_cell_hs_.insert(ch);
			}
		}
	}

	cur_it_ = neighb_sheet_cell_hs_.begin();
	BaseIter::valid(cur_it_ != neighb_sheet_cell_hs_.end());
	if(BaseIter::valid()) {
		BaseIter::cur_handle(*cur_it_);
	}
}

87 88

CellSheetCellIter& CellSheetCellIter::operator--() {
89 90 91 92 93 94 95 96 97 98

    if(cur_it_ == neighb_sheet_cell_hs_.begin()) {
        BaseIter::valid(false);
    } else {
        --cur_it_;
        BaseIter::cur_handle(*cur_it_);
    }
    return *this;
}

99 100

CellSheetCellIter& CellSheetCellIter::operator++() {
101 102 103 104 105 106 107 108 109 110 111 112 113 114

    ++cur_it_;
	if(cur_it_ != neighb_sheet_cell_hs_.end()) {
		BaseIter::cur_handle(*cur_it_);
	} else {
		BaseIter::valid(false);
	}
	return *this;
}

//================================================================================================
// HalfFaceSheetHalfFaceIter
//================================================================================================

115 116 117

HalfFaceSheetHalfFaceIter::HalfFaceSheetHalfFaceIter(const HalfFaceHandle& _ref_h,
        const HexahedralMeshTopologyKernel* _mesh) :
118 119
BaseIter(_mesh, _ref_h) {

120
	if(!_mesh->has_face_bottom_up_adjacencies()) {
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
        std::cerr << "This iterator needs bottom-up adjacencies!" << std::endl;
        BaseIter::valid(false);
        return;
    }

	/*
	 * Each halfface uniquely belongs to either a cell
	 * or the boundary. If the halfface belongs
	 * to a cell, it suffices to determine the local axis
	 * the halfface represents w.r.t. the cell and to
	 * iterate over all neighboring cells orthogonal to
	 * this direction. We have to find those halffaces
	 * of the neighboring cells that contain exactly one
	 * of the initial halfface's opposite halfedges.
	 */

	if(_mesh->is_boundary(_ref_h)) {
		std::cerr << "HalfFaceSheetHalfFaceIter: HalfFace is boundary!" << std::endl;
		BaseIter::valid(false);
        return;
	}

	CellHandle ch = _mesh->incident_cell(_ref_h);
	unsigned char orientation = _mesh->orientation(_ref_h, ch);
	std::vector<HalfEdgeHandle> hes_v = _mesh->opposite_halfface(_mesh->halfface(_ref_h)).halfedges();
	std::set<HalfEdgeHandle> hes;
	hes.insert(hes_v.begin(), hes_v.end());

149
	for(CellSheetCellIter csc_it = _mesh->csc_iter(ch, orientation);
150 151 152
			csc_it.valid(); ++csc_it) {

		std::vector<HalfFaceHandle> hfs = _mesh->cell(*csc_it).halffaces();
153
		for(std::vector<HalfFaceHandle>::const_iterator hf_it = hfs.begin();
154 155 156
				hf_it != hfs.end(); ++hf_it) {

			std::vector<HalfEdgeHandle> hf_hes = _mesh->halfface(*hf_it).halfedges();
157
			for(std::vector<HalfEdgeHandle>::const_iterator he_it = hf_hes.begin();
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
					he_it != hf_hes.end(); ++he_it) {

				if(hes.count(*he_it) > 0) {
					// Found halfface that lies on the same sheet
					adjacent_halffaces_.push_back(*hf_it);
					common_edges_.push_back(_mesh->edge_handle(*he_it));
					break;
				}
			}
		}
	}

	cur_it_ = adjacent_halffaces_.begin();
	edge_it_ = common_edges_.begin();
    BaseIter::valid(cur_it_ != adjacent_halffaces_.end());
    if(BaseIter::valid()) {
    	BaseIter::cur_handle(*cur_it_);
    }
}

178 179

HalfFaceSheetHalfFaceIter& HalfFaceSheetHalfFaceIter::operator--() {
180 181 182 183 184 185 186 187 188 189 190

    --cur_it_;
    --edge_it_;
    if(cur_it_ >= adjacent_halffaces_.begin()) {
		BaseIter::cur_handle(*cur_it_);
	} else {
		BaseIter::valid(false);
	}
    return *this;
}

191 192

HalfFaceSheetHalfFaceIter& HalfFaceSheetHalfFaceIter::operator++() {
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207

    ++cur_it_;
    ++edge_it_;
	if(cur_it_ != adjacent_halffaces_.end()) {
		BaseIter::cur_handle(*cur_it_);
	} else {
		BaseIter::valid(false);
	}
	return *this;
}

//================================================================================================
// OutsideNeighborHalfFaceIter
//================================================================================================

208 209 210

OutsideNeighborHalfFaceIter::OutsideNeighborHalfFaceIter(const HalfFaceHandle& _ref_h,
        const HexahedralMeshTopologyKernel* _mesh) :
211 212
BaseIter(_mesh, _ref_h) {

213
    if(!_mesh->has_face_bottom_up_adjacencies()) {
214 215 216 217 218 219 220
        std::cerr << "This iterator needs bottom-up adjacencies!" << std::endl;
        BaseIter::valid(false);
        return;
    }

    // Go over all incident halfedges
    std::vector<HalfEdgeHandle> halfedges = _mesh->halfface(_ref_h).halfedges();
221
    for(std::vector<HalfEdgeHandle>::const_iterator he_it = halfedges.begin();
222 223 224
            he_it != halfedges.end(); ++he_it) {

        // Get outside halffaces
225
        OpenVolumeMesh::HalfEdgeHalfFaceIter hehf_it = _mesh->hehf_iter(_mesh->opposite_halfedge_handle(*he_it));
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
        for(; hehf_it.valid(); ++hehf_it) {

            if(_mesh->is_boundary(*hehf_it)) {
                neighbor_halffaces_.push_back(*hehf_it);
                common_edges_.push_back(_mesh->edge_handle(*he_it));
            }
        }
    }

    cur_it_ = neighbor_halffaces_.begin();
    edge_it_ = common_edges_.begin();
    BaseIter::valid(cur_it_ != neighbor_halffaces_.end());
    if(BaseIter::valid()) {
        BaseIter::cur_handle(*cur_it_);
    }
}

243 244

OutsideNeighborHalfFaceIter& OutsideNeighborHalfFaceIter::operator--() {
245 246 247 248 249 250 251 252 253 254 255

    --cur_it_;
    --edge_it_;
    if(cur_it_ >= neighbor_halffaces_.begin()) {
        BaseIter::cur_handle(*cur_it_);
    } else {
        BaseIter::valid(false);
    }
    return *this;
}

256 257

OutsideNeighborHalfFaceIter& OutsideNeighborHalfFaceIter::operator++() {
258 259 260 261 262 263 264 265 266 267 268 269

    ++cur_it_;
    ++edge_it_;
    if(cur_it_ != neighbor_halffaces_.end()) {
        BaseIter::cur_handle(*cur_it_);
    } else {
        BaseIter::valid(false);
    }
    return *this;
}

} // Namespace OpenVolumeMesh