------------------------------------------------------------------------------
| 1129 | |
| 1130 | //------------------------------------------------------------------------------ |
| 1131 | vtkSmartPointer<vtkPolyData> vtkProbeLineFilter::IntersectCells( |
| 1132 | const vtkVector3d& p1, const vtkVector3d& p2, vtkDataSet* dataset, double tolerance) const |
| 1133 | { |
| 1134 | auto result = vtkSmartPointer<vtkPolyData>::New(); |
| 1135 | |
| 1136 | // Get all cell intersections for the current dataset. There is some cases where there |
| 1137 | // is no strategy associated to a dataset, usually because the dataset has 0 cells. |
| 1138 | // In this case `intersections` will stay empty. |
| 1139 | std::vector<HitCellInfo> intersections; |
| 1140 | auto* strategy = vtkCellLocatorStrategy::SafeDownCast(this->Internal->Strategies[dataset]); |
| 1141 | if (strategy) |
| 1142 | { |
| 1143 | vtkAbstractCellLocator* locator = strategy->GetCellLocator(); |
| 1144 | vtkNew<vtkIdList> intersectedIds; |
| 1145 | locator->FindCellsAlongLine(p1.GetData(), p2.GetData(), 0.0, intersectedIds); |
| 1146 | for (vtkIdType i = 0; i < intersectedIds->GetNumberOfIds(); ++i) |
| 1147 | { |
| 1148 | vtkIdType cellId = intersectedIds->GetId(i); |
| 1149 | if (dataset->HasAnyGhostCells() && dataset->GetCellGhostArray()->GetValue(cellId)) |
| 1150 | { |
| 1151 | continue; |
| 1152 | } |
| 1153 | |
| 1154 | auto inOut = ::GetInOutCell(p1, p2, cellId, dataset, tolerance); |
| 1155 | const bool isNotDuplicate = intersections.empty() || intersections.back() != inOut; |
| 1156 | if (inOut && isNotDuplicate) |
| 1157 | { |
| 1158 | intersections.emplace_back(inOut); |
| 1159 | } |
| 1160 | } |
| 1161 | } |
| 1162 | |
| 1163 | // Make sure our intersections are sorted |
| 1164 | vtkSMPTools::Sort(intersections.begin(), intersections.end()); |
| 1165 | |
| 1166 | // Create a point cloud also storing point and cells data for these intersections |
| 1167 | vtkNew<vtkPoints> linePoints; |
| 1168 | const double lineLength = (p2 - p1).Norm(); |
| 1169 | auto arclengthArray = ::CreatePoints(intersections, linePoints, lineLength); |
| 1170 | result->SetPoints(linePoints); |
| 1171 | |
| 1172 | // Interpolate point data to intersection locations |
| 1173 | vtkPointData* resultPointData = result->GetPointData(); |
| 1174 | resultPointData->AddArray(arclengthArray); |
| 1175 | auto* inputPointData = dataset->GetPointData(); |
| 1176 | for (int i = 0; i < inputPointData->GetNumberOfArrays(); ++i) |
| 1177 | { |
| 1178 | vtkAbstractArray* sourceArray = inputPointData->GetAbstractArray(i); |
| 1179 | if (auto targetArray = |
| 1180 | ::AddAttribute(sourceArray, resultPointData, linePoints->GetNumberOfPoints())) |
| 1181 | { |
| 1182 | for (size_t j = 0; j < intersections.size(); ++j) |
| 1183 | { |
| 1184 | const auto& inter = intersections[j]; |
| 1185 | vtkCell* cell = dataset->GetCell(inter.CellId); |
| 1186 | |
| 1187 | std::vector<double> weights(cell->GetNumberOfPoints()); |
| 1188 | cell->InterpolateFunctions(inter.InPCoords.data(), weights.data()); |
no test coverage detected