vtkDataArray * avtPolarCoordinatesExpression::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex) { vtkIdType npts = in_ds->GetNumberOfPoints(); vtkDataArray *rv = CreateArrayFromMesh(in_ds); rv->SetNumberOfComponents(3); rv->SetNumberOfTuples(npts); bool in3D = (GetInput()->GetInfo().GetAttributes().GetSpatialDimension() == 3); for (vtkIdType i = 0 ; i < npts ; i++) { double pt[3]; in_ds->GetPoint(i, pt); double r = sqrt(pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]); rv->SetComponent(i, 0, r); double theta = atan2(pt[1], pt[0]); rv->SetComponent(i, 1, theta); double phi = 0.; if (in3D && r != 0) phi = acos(pt[2] / r); else phi = 0; rv->SetComponent(i, 2, phi); } return rv; }
vtkDataArray * avtFacePlanarity::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex) { vtkDataArray *arr = CreateArrayFromMesh(in_ds); vtkIdType ncells = in_ds->GetNumberOfCells(); arr->SetNumberOfTuples(ncells); for (vtkIdType i = 0 ; i < ncells ; i++) { vtkCell *cell = in_ds->GetCell(i); double vol = GetFacePlanarityForCell(cell, takeRel); arr->SetTuple1(i, vol); } return arr; }
vtkDataArray * avtRevolvedVolume::DeriveVariable(vtkDataSet *in_ds) { vtkDataArray *arr = CreateArrayFromMesh(in_ds); vtkIdType ncells = in_ds->GetNumberOfCells(); arr->SetNumberOfTuples(ncells); for (vtkIdType i = 0 ; i < ncells ; i++) { vtkCell *cell = in_ds->GetCell(i); double vol = GetZoneVolume(cell); arr->SetTuple1(i, vol); } return arr; }
vtkDataArray * avtMinCornerArea::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex) { vtkDataArray *arr = CreateArrayFromMesh(in_ds); vtkIdType ncells = in_ds->GetNumberOfCells(); arr->SetNumberOfTuples(ncells); for (vtkIdType i = 0 ; i < ncells ; i++) { vtkCell *cell = in_ds->GetCell(i); double mcar = GetMinCornerArea(cell); arr->SetTuple1(i, mcar); } return arr; }
vtkDataArray * avtSurfaceNormalExpression::RectilinearDeriveVariable(vtkRectilinearGrid *rgrid) { int dims[3]; rgrid->GetDimensions(dims); int nMatch = 0; bool doX = (dims[0] == 1); if (doX) nMatch++; bool doY = (dims[1] == 1); if (doY) nMatch++; bool doZ = (dims[2] == 1); if (doZ) nMatch++; if (nMatch == 0) { EXCEPTION2(ExpressionException, outputVariableName, "Can not determine " "surface normals for a 3D data set."); } if (nMatch > 1) { EXCEPTION2(ExpressionException, outputVariableName, "Can not determine " "surface normals for lines and vertices."); } vtkDataArray *n = CreateArrayFromMesh(rgrid); n->SetNumberOfComponents(3); vtkIdType ntuples = (isPoint ? rgrid->GetNumberOfPoints() : rgrid->GetNumberOfCells()); n->SetNumberOfTuples(ntuples); double norm[3] = { 0, 0, 0 }; if (doX) norm[0] = 1.0; if (doY) norm[1] = 1.0; if (doZ) norm[2] = 1.0; for (vtkIdType i = 0 ; i < ntuples ; i++) { n->SetTuple(i, norm); } return n; }
vtkDataArray * avtCylindricalCoordinatesExpression::DeriveVariable(vtkDataSet *in_ds) { vtkIdType npts = in_ds->GetNumberOfPoints(); vtkDataArray *rv = CreateArrayFromMesh(in_ds); rv->SetNumberOfComponents(3); rv->SetNumberOfTuples(npts); for (vtkIdType i = 0 ; i < npts ; i++) { double pt[3]; in_ds->GetPoint(i, pt); double r = sqrt(pt[0]*pt[0] + pt[1]*pt[1]); rv->SetComponent(i, 0, r); double theta = atan2(pt[1], pt[0]); rv->SetComponent(i, 1, theta); rv->SetComponent(i, 2, pt[2]); } return rv; }
vtkDataArray * avtCylindricalRadiusExpression::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex) { vtkIdType npts = in_ds->GetNumberOfPoints(); vtkDataArray *rv = CreateArrayFromMesh(in_ds); rv->SetNumberOfComponents(1); rv->SetNumberOfTuples(npts); // The cylindrical radius is: // norm(pt) * sin(acos(dot(pt,axis)/(norm(pt)*norm(axis)))) // avtVector ax_vec(axisVector); ax_vec.normalize(); for (vtkIdType i = 0 ; i < npts ; i++) { double pt[3]; in_ds->GetPoint(i, pt); avtVector pt_vec(pt); double pt_vec_mag = pt_vec.norm(); // dot prod of normalized vecs to get angle double dp = pt_vec * ax_vec; dp = dp / pt_vec_mag ; double ang = acos(dp); // find the orthogonal component avtVector proj = pt_vec * sin(ang); double r = proj.norm(); rv->SetComponent(i, 0, r); } return rv; }
vtkDataArray * avtUnaryMathExpression::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex) { int i; vtkDataArray *cell_data = NULL; vtkDataArray *point_data = NULL; vtkDataArray *data = NULL; if (activeVariable == NULL) { // // This hack is getting more and more refined. This situation comes up // when we don't know what the active variable is (mostly for the // constant creation filter). We probably need more infrastructure // to handle this. // Iteration 1 of this hack said take any array. // Iteration 2 said take any array that isn't vtkGhostLevels, etc. // Iteration 3 says take the first scalar array if one is available, // provided that array is not vtkGhostLevels, etc. // This is because most constants we create are scalar. // // Note: this hack used to be quite important because we would use // the resulting array to determine the centering of the variable. // Now we use the IsPointVariable() method. So this data array is // only used to get the type. // int ncellArray = in_ds->GetCellData()->GetNumberOfArrays(); for (i = 0 ; i < ncellArray ; i++) { vtkDataArray *candidate = in_ds->GetCellData()->GetArray(i); if (strstr(candidate->GetName(), "vtk") != NULL) continue; if (strstr(candidate->GetName(), "avt") != NULL) continue; if (candidate->GetNumberOfComponents() == 1) { // Definite winner cell_data = candidate; break; } else // Potential winner -- keep looking cell_data = candidate; } int npointArray = in_ds->GetPointData()->GetNumberOfArrays(); for (i = 0 ; i < npointArray ; i++) { vtkDataArray *candidate = in_ds->GetPointData()->GetArray(i); if (strstr(candidate->GetName(), "vtk") != NULL) continue; if (strstr(candidate->GetName(), "avt") != NULL) continue; if (candidate->GetNumberOfComponents() == 1) { // Definite winner point_data = candidate; break; } else // Potential winner -- keep looking point_data = candidate; } if (cell_data != NULL && cell_data->GetNumberOfComponents() == 1) { data = cell_data; centering = AVT_ZONECENT; } else if (point_data != NULL && point_data->GetNumberOfComponents()== 1) { data = point_data; centering = AVT_NODECENT; } else if (cell_data != NULL) { data = cell_data; centering = AVT_ZONECENT; } else { data = point_data; centering = AVT_NODECENT; } } else { cell_data = in_ds->GetCellData()->GetArray(activeVariable); point_data = in_ds->GetPointData()->GetArray(activeVariable); if (cell_data != NULL) { data = cell_data; centering = AVT_ZONECENT; } else { data = point_data; centering = AVT_NODECENT; } } // // Set up a VTK variable reflecting the calculated variable // int ncomps = 0; int nvals = 0; if (FilterCreatesSingleton()) nvals = 1; else if (activeVariable == NULL || data == NULL) nvals = (IsPointVariable() ? in_ds->GetNumberOfPoints() : in_ds->GetNumberOfCells()); else nvals = data->GetNumberOfTuples(); vtkDataArray *dv = NULL; if (data == NULL) { // // We could not find a single array. We must be doing something with // the mesh. // ncomps = 1; dv = CreateArrayFromMesh(in_ds); } else { ncomps = data->GetNumberOfComponents(); dv = CreateArray(data); } if (data == NULL) { if (! NullInputIsExpected()) { // One way to get here is to have vtkPolyData Curve plots. EXCEPTION2(ExpressionException, outputVariableName, "An internal error occurred when " "trying to calculate your expression. Please contact a " "VisIt developer."); } } int noutcomps = GetNumberOfComponentsInOutput(ncomps); dv->SetNumberOfComponents(noutcomps); dv->SetNumberOfTuples(nvals); // // Should we send in ncomps or noutcomps? They are the same number // unless the derived type re-defined GetNumberOfComponentsInOutput. // If it did, it probably doesn't matter. If not, then it is the same // number. So send in the input. Really doesn't matter. // cur_mesh = in_ds; DoOperation(data, dv, ncomps, nvals); cur_mesh = NULL; return dv; }
avtDataRepresentation * avtNeighborExpression::ExecuteData(avtDataRepresentation *in_dr) { // // Get the VTK data set. // vtkDataSet *in_ds = in_dr->GetDataVTK(); // Let's get the points from the input dataset. vtkPoints *pts = NULL; switch (in_ds->GetDataObjectType()) { // Easily done, just grab them. case VTK_UNSTRUCTURED_GRID: case VTK_POLY_DATA: case VTK_STRUCTURED_GRID: pts = ((vtkPointSet *) in_ds)->GetPoints(); break; // If they're any other type of grid, this filter shouldn't be used default: EXCEPTION0(ImproperUseException); } vtkIdType nPoints = pts->GetNumberOfPoints(); // A neighbor filter would require the existance of neighbors if (nPoints < 2) EXCEPTION0(ImproperUseException); // Now that we've done all of our checks for improper use, // let's allocate for our needs vtkPolyData *results = vtkPolyData::New(); vtkCellArray *verts = vtkCellArray::New(); vtkDataArray *data = CreateArrayFromMesh(in_ds); results->SetPoints(pts); data->SetNumberOfComponents(1); data->SetNumberOfTuples(nPoints); double bounds[6]; in_ds->GetBounds(bounds); // Create the point locator vtkPointLocator *ptLoc = vtkPointLocator::New(); ptLoc->SetDataSet(in_ds); ptLoc->BuildLocator(); for (vtkIdType id = 0; id < nPoints; id++) { // Build the vertex list vtkVertex *v = vtkVertex::New(); v->Initialize( 1, &id, pts); verts->InsertNextCell(v); v->Delete(); // And at the same time, set the distance data double coords[3]; pts->GetPoint(id, coords); // Find the closest 2 points, since the closest is itself of course. vtkIdList *closeId = vtkIdList::New(); ptLoc->FindClosestNPoints(2, coords, closeId); double nearCoords[3]; pts->GetPoint(closeId->GetId(1), nearCoords); double distance = (coords[0]-nearCoords[0])*(coords[0]-nearCoords[0]) + (coords[1]-nearCoords[1])*(coords[1]-nearCoords[1]) + (coords[2]-nearCoords[2])*(coords[2]-nearCoords[2]); distance=sqrt(distance); data->SetTuple1(id, distance); closeId->Delete(); } data->SetName("neighbor"); results->GetPointData()->AddArray(data); results->GetPointData()->SetActiveScalars("neighbor"); results->SetVerts(verts); // // Make our best attempt at maintaining our extents. // double exts[2]; double range[2]; data->GetRange(range, 0); exts[0] = range[0]; exts[1] = range[1]; GetOutput()->GetInfo().GetAttributes().GetOriginalDataExtents()->Merge(exts); data->Delete(); verts->Delete(); pts->Delete(); avtDataRepresentation *out_dr = new avtDataRepresentation(results, in_dr->GetDomain(), in_dr->GetLabel()); results->Delete(); return out_dr; }
vtkDataArray * avtRevolvedSurfaceArea::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex) { // // Create a copy of the input with each zone's id number. This will be // used to match up the line segments with the zones they came from later. // vtkDataSet *tmp_ds = in_ds->NewInstance(); tmp_ds->ShallowCopy(in_ds); vtkIdType n_orig_cells = tmp_ds->GetNumberOfCells(); vtkIntArray *iarray = vtkIntArray::New(); iarray->SetName("_rsa_ncells"); iarray->SetNumberOfTuples(n_orig_cells); for (vtkIdType i = 0 ; i < n_orig_cells ; i++) iarray->SetValue(i, i); tmp_ds->GetCellData()->AddArray(iarray); iarray->Delete(); // // Create the boundary edges. // vtkGeometryFilter *geomFilter = vtkGeometryFilter::New(); vtkVisItFeatureEdges *boundaryFilter = vtkVisItFeatureEdges::New(); vtkPolyData *allLines = NULL; avtDataAttributes &atts = GetInput()->GetInfo().GetAttributes(); if (atts.GetTopologicalDimension() == 2) { geomFilter->SetInputData(tmp_ds); boundaryFilter->BoundaryEdgesOn(); boundaryFilter->FeatureEdgesOff(); boundaryFilter->NonManifoldEdgesOff(); boundaryFilter->ManifoldEdgesOff(); boundaryFilter->ColoringOff(); boundaryFilter->SetInputConnection(geomFilter->GetOutputPort()); vtkStreamingDemandDrivenPipeline::SetUpdateGhostLevel(boundaryFilter->GetInformation(), 2); boundaryFilter->Update(); allLines = boundaryFilter->GetOutput(); } else if (tmp_ds->GetDataObjectType() == VTK_POLY_DATA) { allLines = (vtkPolyData *) tmp_ds; } else { geomFilter->SetInputData(tmp_ds); allLines = geomFilter->GetOutput(); } // // Remove ghost zones. // vtkDataSetRemoveGhostCells *gzFilter = vtkDataSetRemoveGhostCells::New(); gzFilter->SetInputData(allLines); gzFilter->Update(); vtkDataSet *ds_1d_nogz = gzFilter->GetOutput(); // We need line segment polydata, and should have it by now. if (ds_1d_nogz->GetDataObjectType() != VTK_POLY_DATA) { tmp_ds->Delete(); geomFilter->Delete(); gzFilter->Delete(); boundaryFilter->Delete(); debug1 << "ERROR:Did not get polydata from ghost zone filter output\n"; return NULL; } vtkPolyData *pd_1d_nogz = (vtkPolyData*)ds_1d_nogz; // // Only some of the zones are actually external to the domain and // contribute to the resolved surface area. These zones are exactly // the zones in pd_1d_nogz. But we need to create an output that is // sized for the input mesh. So construct an array with all 0's (the // zones that aren't on the exterior contribute 0 surface area) and then // add in the contributions from the zones on the exterior. // vtkDataArray *arr = CreateArrayFromMesh(in_ds); arr->SetNumberOfTuples(n_orig_cells); for (vtkIdType i = 0 ; i < n_orig_cells ; i++) arr->SetTuple1(i, 0.); vtkIdType ncells = pd_1d_nogz->GetNumberOfCells(); vtkIntArray *orig_cells = (vtkIntArray *) pd_1d_nogz->GetCellData()->GetArray("_rsa_ncells"); for (vtkIdType i = 0 ; i < ncells ; i++) { vtkCell *cell = pd_1d_nogz->GetCell(i); double area = GetCellArea(cell); int orig_cell = orig_cells->GetValue(i); double orig_area = arr->GetTuple1(orig_cell); double new_area = area + orig_area; arr->SetTuple1(orig_cell, new_area); } // // Clean up. // tmp_ds->Delete(); geomFilter->Delete(); gzFilter->Delete(); boundaryFilter->Delete(); return arr; }