void avtSurfaceFilter::PreExecute(void) { avtDataTreeIterator::PreExecute(); if (stillNeedExtents) { const char *varname = pipelineVariable; if (atts.GetVariable() != "default") varname = atts.GetVariable().c_str(); double dataExtents[2]; double spatialExtents[6]; GetDataExtents(dataExtents, varname); avtDataset_p input = GetTypedInput(); avtDatasetExaminer::GetSpatialExtents(input, spatialExtents); UnifyMinMax(spatialExtents,6); CalculateScaleValues(dataExtents, spatialExtents); } zValMin = +FLT_MAX; zValMax = -FLT_MAX; haveIssuedWarning = false; }
void avtDataBinningFilter::Execute(void) { ConstructDataBinningAttributes dba = atts.CreateConstructionAtts(); std::vector<double> bb = dba.GetBinBoundaries(); if (! atts.GetDim1SpecifyRange()) { if (atts.GetDim1BinBasedOn() == DataBinningAttributes::Variable) { std::string v1name = atts.GetDim1Var(); if (v1name == "default") v1name = pipelineVariable; double range[2]; GetDataExtents(range, v1name.c_str()); bb[0] = range[0]; bb[1] = range[1]; } else { int dim = (atts.GetDim1BinBasedOn()-DataBinningAttributes::X); double range[6]; GetSpatialExtents(range); bb[0] = range[2*dim]; bb[1] = range[2*dim+1]; } } if ((! atts.GetDim2SpecifyRange()) && (atts.GetNumDimensions() == DataBinningAttributes::Two || atts.GetNumDimensions() == DataBinningAttributes::Three)) { if (atts.GetDim2BinBasedOn() == DataBinningAttributes::Variable) { std::string v2name = atts.GetDim2Var(); if (v2name == "default") v2name = pipelineVariable; double range[2]; GetDataExtents(range, v2name.c_str()); bb[2] = range[0]; bb[3] = range[1]; } else { int dim = (atts.GetDim2BinBasedOn()-DataBinningAttributes::X); double range[6]; GetSpatialExtents(range); bb[2] = range[2*dim]; bb[3] = range[2*dim+1]; } } if ((! atts.GetDim3SpecifyRange()) && atts.GetNumDimensions() == DataBinningAttributes::Three) { if (atts.GetDim3BinBasedOn() == DataBinningAttributes::Variable) { std::string v3name = atts.GetDim3Var(); if (v3name == "default") v3name = pipelineVariable; double range[2]; GetDataExtents(range, v3name.c_str()); bb[4] = range[0]; bb[5] = range[1]; } else { int dim = (atts.GetDim3BinBasedOn()-DataBinningAttributes::X); double range[6]; GetSpatialExtents(range); bb[4] = range[2*dim]; bb[5] = range[2*dim+1]; } } dba.SetBinBoundaries(bb); avtDataBinningConstructor dbc; dbc.SetInput(GetInput()); avtDataBinning *d = dbc.ConstructDataBinning(&dba, lastContract, false); if (atts.GetOutputType() == DataBinningAttributes::OutputOnBins) { if (PAR_Rank() == 0) { vtkDataSet *ds = d->CreateGrid(); if (atts.GetNumDimensions() == DataBinningAttributes::One) ds->GetPointData()->GetScalars()->SetName(varname.c_str()); else ds->GetCellData()->GetScalars()->SetName(varname.c_str()); ds->GetCellData()->SetActiveScalars(varname.c_str()); SetOutputDataTree(new avtDataTree(ds, -1)); double range[2] = { FLT_MAX, -FLT_MAX }; GetDataRange(ds, range, varname.c_str(), false); avtDataAttributes &dataAtts = GetOutput()->GetInfo().GetAttributes(); dataAtts.GetThisProcsOriginalDataExtents(varname.c_str())->Set(range); dataAtts.GetThisProcsActualDataExtents(varname.c_str())->Set(range); ds->Delete(); } else SetOutputDataTree(new avtDataTree()); avtDataAttributes &dataAtts = GetOutput()->GetInfo().GetAttributes(); int dim = ( (atts.GetNumDimensions() == DataBinningAttributes::One) ? 1 : ((atts.GetNumDimensions() == DataBinningAttributes::Two) ? 2 : 3)); dataAtts.GetThisProcsOriginalSpatialExtents()->Set(&bb[0]); dataAtts.GetOriginalSpatialExtents()->Set(&bb[0]); } else if (atts.GetOutputType() == DataBinningAttributes::OutputOnInputMesh) { double range[2] = { FLT_MAX, -FLT_MAX }; bool hadError = false; avtDataTree_p tree = CreateArrayFromDataBinning(GetInputDataTree(), d, range, hadError); if (UnifyMaximumValue((int) hadError) > 0) { avtCallback::IssueWarning("The data binning could not be placed on the input " "mesh. This is typically because the data binning is over different " "centerings (zonal and nodal) and can not be meaningfully placed back " "on the input mesh. Try recentering one of the variables to remove " "this ambiguity."); SetOutputDataTree(new avtDataTree()); } else { SetOutputDataTree(tree); avtDataAttributes &dataAtts = GetOutput()->GetInfo().GetAttributes(); dataAtts.GetThisProcsOriginalDataExtents(varname.c_str())->Set(range); dataAtts.GetThisProcsActualDataExtents(varname.c_str())->Set(range); } } delete d; }
void avtResampleFilter::ResampleInput(void) { int i, j, k; avtDataset_p output = GetTypedOutput(); double bounds[6] = { 0, 0, 0, 0, 0, 0 }; bool is3D = GetBounds(bounds); debug4 << "Resampling over space: " << bounds[0] << ", " << bounds[1] << ": " << bounds[2] << ", " << bounds[3] << ": " << bounds[4] << ", " << bounds[5] << endl; // // Our resampling leaves some invalid values in the data range. The // easiest way to bypass this is to get the data range from the input and // pass it along (since resampling does not change it in theory). // double range[2]; if (GetInput()->GetInfo().GetAttributes().ValidActiveVariable()) { GetDataExtents(range); output->GetInfo().GetAttributes().GetDesiredDataExtents()->Set(range); } avtViewInfo view; double scale[3]; CreateViewFromBounds(view, bounds, scale); // // What we want the width, height, and depth to be depends on the // attributes. // int width, height, depth; GetDimensions(width, height, depth, bounds, is3D); // // If there are no variables, then just create the mesh and exit. // bool thereAreNoVariables = (GetInput()->GetInfo().GetAttributes().GetNumberOfVariables() <= 0); if (thereAreNoVariables) { if (PAR_Rank() == 0) { vtkRectilinearGrid *rg = CreateGrid(bounds, width, height, depth, 0, width, 0, height, cellCenteredOutput, is3D); avtDataTree_p tree = new avtDataTree(rg, 0); rg->Delete(); SetOutputDataTree(tree); } else { // // Putting in a NULL data tree can lead to seg faults, etc. // avtDataTree_p dummy = new avtDataTree(); SetOutputDataTree(dummy); } return; } // // World space is a right-handed coordinate system. Image space (as used // in the sample point extractor) is a left-handed coordinate system. // This is because large X is at the right and large Y is at the top. // The z-buffer has the closest points at z=0, so Z is going away from the // screen ===> left handed coordinate system. If we reflect across X, // then this will account for the difference between the coordinate // systems. // scale[0] *= -1.; // // We don't want an Update to go all the way up the pipeline, so make // a terminating source corresponding to our input. // avtDataset_p ds; avtDataObject_p dObj = GetInput(); CopyTo(ds, dObj); avtSourceFromAVTDataset termsrc(ds); // // The sample point extractor expects everything to be in image space. // avtWorldSpaceToImageSpaceTransform trans(view, scale); trans.SetInput(termsrc.GetOutput()); bool doKernel = (GetInput()->GetInfo().GetAttributes().GetTopologicalDimension() == 0); avtSamplePointExtractor extractor(width, height, depth); extractor.SendCellsMode(false); extractor.Set3DMode(is3D); extractor.SetInput(trans.GetOutput()); if (doKernel) extractor.SetKernelBasedSampling(true); avtSamplePoints_p samples = extractor.GetTypedOutput(); // // If the selection this filter exists to create has already been handled, // or if there are no pieces for this processor to process, then we can skip // execution. But, take care to emulate the same collective // calls other processors may make before returning. // if (GetInput()->GetInfo().GetAttributes().GetSelectionApplied(selID)) { debug1 << "Bypassing Resample operator because database plugin " "claims to have applied the selection already" << endl; SetOutputDataTree(GetInputDataTree()); // we can save a lot of time if we know everyone can bypass if (UnifyMaximumValue(0) == 0) return; // here is some dummied up code to match collective calls below int effectiveVars = samples->GetNumberOfRealVariables(); double *ptrtmp = new double[width*height*depth]; for (int jj = 0; jj < width*height*depth; jj++) ptrtmp[jj] = -FLT_MAX; for (i = 0 ; i < effectiveVars ; i++) Collect(ptrtmp, width*height*depth); delete [] ptrtmp; return; } else { UnifyMaximumValue(1); } // // // PROBLEM SIZED WORK OCCURS BEYOND THIS POINT // If you add (or remove) collective calls below this point, make sure to // put matching sequence into bypass code above // // avtSamplePointCommunicator communicator; avtImagePartition partition(width, height, PAR_Size(), PAR_Rank()); communicator.SetImagePartition(&partition); bool doDistributedResample = false; #ifdef PARALLEL doDistributedResample = atts.GetDistributedResample(); #endif if (doDistributedResample) { partition.SetShouldProduceOverlaps(true); avtDataObject_p dob; CopyTo(dob, samples); communicator.SetInput(dob); samples = communicator.GetTypedOutput(); } // Always set up an arbitrator, even if user selected random. bool arbLessThan = !atts.GetUseArbitrator() || atts.GetArbitratorLessThan(); std::string arbName = atts.GetArbitratorVarName(); if (arbName == "default") arbName = primaryVariable; extractor.SetUpArbitrator(arbName, arbLessThan); // // Since this is Execute, forcing an update is okay... // samples->Update(GetGeneralContract()); if (samples->GetInfo().GetValidity().HasErrorOccurred()) { GetOutput()->GetInfo().GetValidity().ErrorOccurred(); GetOutput()->GetInfo().GetValidity().SetErrorMessage( samples->GetInfo().GetValidity().GetErrorMessage()); } // // Create a rectilinear dataset that is stretched according to the // original bounds. // int width_start = 0; int width_end = width; int height_start = 0; int height_end = height; if (doDistributedResample) { partition.GetThisPartition(width_start, width_end, height_start, height_end); width_end += 1; height_end += 1; } // // If we have more processors than domains, we have to handle that // gracefully. Communicate how many variables there are so that those // that don't have data can play well. // int realVars = samples->GetNumberOfRealVariables(); int numArrays = realVars; if (doKernel) numArrays++; vtkDataArray **vars = new vtkDataArray*[numArrays]; for (i = 0 ; i < numArrays ; i++) { vars[i] = vtkDoubleArray::New(); if (doKernel && (i == numArrays-1)) vars[i]->SetNumberOfComponents(1); else { vars[i]->SetNumberOfComponents(samples->GetVariableSize(i)); vars[i]->SetName(samples->GetVariableName(i).c_str()); } } if (doKernel) samples->GetVolume()->SetUseKernel(true); avtImagePartition *ip = NULL; if (doDistributedResample) ip = &partition; // We want all uncovered regions to get the default value. That is // what the first argument of GetVariables is for. But if the // default value is large, then it will screw up the collect call below, // which uses MPI_MAX for an all reduce. So give uncovered regions very // small values now (-FLT_MAX) and then replace them later. double defaultPlaceholder = -FLT_MAX; samples->GetVolume()->GetVariables(defaultPlaceholder, vars, numArrays, ip); if (!doDistributedResample) { // // Collect will perform the parallel collection. Does nothing in // serial. This will only be valid on processor 0. // for (i = 0 ; i < numArrays ; i++) { double *ptr = (double *) vars[i]->GetVoidPointer(0); Collect(ptr, vars[i]->GetNumberOfComponents()*width*height*depth); } } // Now replace the -FLT_MAX's with the default value. (See comment above.) for (i = 0 ; i < numArrays ; i++) { int numTups = vars[i]->GetNumberOfComponents() * vars[i]->GetNumberOfTuples(); if (numTups > 0) { double *ptr = (double *) vars[i]->GetVoidPointer(0); for (j = 0 ; j < numTups ; j++) ptr[j] = (ptr[j] == defaultPlaceholder ? atts.GetDefaultVal() : ptr[j]); } } bool iHaveData = false; if (doDistributedResample) iHaveData = true; if (PAR_Rank() == 0) iHaveData = true; if (height_end > height) iHaveData = false; if (iHaveData) { vtkRectilinearGrid *rg = CreateGrid(bounds, width, height, depth, width_start, width_end, height_start, height_end, cellCenteredOutput, is3D); if (doKernel) { double min_weight = avtPointExtractor::GetMinimumWeightCutoff(); vtkDataArray *weights = vars[numArrays-1]; int numVals = weights->GetNumberOfTuples(); for (i = 0 ; i < realVars ; i++) { for (j = 0 ; j < vars[i]->GetNumberOfComponents() ; j++) { for (k = 0 ; k < numVals ; k++) { double weight = weights->GetTuple1(k); if (weight <= min_weight) vars[i]->SetComponent(k, j, atts.GetDefaultVal()); else vars[i]->SetComponent(k, j, vars[i]->GetComponent(k, j) / weight); } } } } // // Attach these variables to our rectilinear grid. // for (i = 0 ; i < realVars ; i++) { const char *varname = vars[i]->GetName(); if (strcmp(varname, primaryVariable) == 0) { if (vars[i]->GetNumberOfComponents() == 3) if (cellCenteredOutput) rg->GetCellData()->SetVectors(vars[i]); else rg->GetPointData()->SetVectors(vars[i]); else if (vars[i]->GetNumberOfComponents() == 1) { if (cellCenteredOutput) { rg->GetCellData()->AddArray(vars[i]); rg->GetCellData()->SetScalars(vars[i]); } else { rg->GetPointData()->AddArray(vars[i]); rg->GetPointData()->SetScalars(vars[i]); } } else { if (cellCenteredOutput) rg->GetCellData()->AddArray(vars[i]); else rg->GetPointData()->AddArray(vars[i]); } } else { if (cellCenteredOutput) rg->GetCellData()->AddArray(vars[i]); else rg->GetPointData()->AddArray(vars[i]); } } avtDataTree_p tree = new avtDataTree(rg, 0); rg->Delete(); SetOutputDataTree(tree); } else { // // Putting in a NULL data tree can lead to seg faults, etc. // avtDataTree_p dummy = new avtDataTree(); SetOutputDataTree(dummy); } for (i = 0 ; i < numArrays ; i++) { vars[i]->Delete(); } delete [] vars; }
avtImage_p avtVolumeFilter::RenderImage(avtImage_p opaque_image, const WindowAttributes &window) { if (atts.GetRendererType() == VolumeAttributes::RayCastingSLIVR){ return RenderImageRaycastingSLIVR(opaque_image,window); } // // We need to create a dummy pipeline with the volume renderer that we // can force to execute within our "Execute". Start with the source. // avtSourceFromAVTDataset termsrc(GetTypedInput()); // // Set up the volume renderer. // avtRayTracer *software = new avtRayTracer; software->SetInput(termsrc.GetOutput()); software->InsertOpaqueImage(opaque_image); software->SetRayCastingSLIVR(false); unsigned char vtf[4*256]; atts.GetTransferFunction(vtf); avtOpacityMap om(256); if ((atts.GetRendererType() == VolumeAttributes::RayCasting) && (atts.GetSampling() == VolumeAttributes::Trilinear)) om.SetTable(vtf, 256, atts.GetOpacityAttenuation()*2.0 - 1.0, atts.GetRendererSamples()); else om.SetTable(vtf, 256, atts.GetOpacityAttenuation()); double actualRange[2]; bool artificialMin = atts.GetUseColorVarMin(); bool artificialMax = atts.GetUseColorVarMax(); if (!artificialMin || !artificialMax) { GetDataExtents(actualRange, primaryVariable); UnifyMinMax(actualRange, 2); } double range[2]; range[0] = (artificialMin ? atts.GetColorVarMin() : actualRange[0]); range[1] = (artificialMax ? atts.GetColorVarMax() : actualRange[1]); if (atts.GetScaling() == VolumeAttributes::Log) { if (artificialMin) if (range[0] > 0) range[0] = log10(range[0]); if (artificialMax) if (range[1] > 0) range[1] = log10(range[1]); } else if (atts.GetScaling() == VolumeAttributes::Skew) { if (artificialMin) { double newMin = vtkSkewValue(range[0], range[0], range[1], atts.GetSkewFactor()); range[0] = newMin; } if (artificialMax) { double newMax = vtkSkewValue(range[1], range[0], range[1], atts.GetSkewFactor()); range[1] = newMax; } } om.SetMin(range[0]); om.SetMax(range[1]); if (atts.GetRendererType() == VolumeAttributes::RayCastingIntegration) { if (!artificialMin) range[0] = 0.; if (!artificialMax) { /* Don't need this code, because the rays will be in depth ... 0->1. double bounds[6]; GetSpatialExtents(bounds); UnifyMinMax(bounds, 6); double diag = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) + (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) + (bounds[5]-bounds[4])*(bounds[5]-bounds[4])); range[1] = (actualRange[1]*diag) / 2.; */ range[1] = (actualRange[1]) / 4.; } } // // Determine which variables to use and tell the ray function. // VarList vl; avtDataset_p input = GetTypedInput(); avtDatasetExaminer::GetVariableList(input, vl); int primIndex = -1; int opacIndex = -1; int gradIndex = -1; int count = 0; char gradName[128]; const char *gradvar = atts.GetOpacityVariable().c_str(); if (strcmp(gradvar, "default") == 0) gradvar = primaryVariable; // This name is explicitly sent to the avtGradientExpression in // the avtVolumePlot. SNPRINTF(gradName, 128, "_%s_gradient", gradvar); for (int i = 0 ; i < vl.nvars ; i++) { if ((strstr(vl.varnames[i].c_str(), "vtk") != NULL) && (strstr(vl.varnames[i].c_str(), "avt") != NULL)) continue; if (vl.varnames[i] == primaryVariable) { primIndex = count; } if (vl.varnames[i] == atts.GetOpacityVariable()) { opacIndex = count; } if (vl.varnames[i] == gradName) { gradIndex = count; } count += vl.varsizes[i]; } if (primIndex == -1) { if (vl.nvars <= 0) { debug1 << "Could not locate primary variable " << primaryVariable << ", assuming that we are running " << "in parallel and have more processors than domains." << endl; } else { EXCEPTION1(InvalidVariableException, primaryVariable); } } if (opacIndex == -1) { if (atts.GetOpacityVariable() == "default") { opacIndex = primIndex; } else if (vl.nvars <= 0) { debug1 << "Could not locate opacity variable " << atts.GetOpacityVariable().c_str() << ", assuming that we " << "are running in parallel and have more processors " << "than domains." << endl; } else { EXCEPTION1(InvalidVariableException,atts.GetOpacityVariable()); } } if ( atts.GetRendererType() != VolumeAttributes::RayCastingIntegration && atts.GetLightingFlag() && gradIndex == -1) { if (vl.nvars <= 0) { debug1 << "Could not locate gradient variable, assuming that we " << "are running in parallel and have more processors " << "than domains." << endl; } else { EXCEPTION1(InvalidVariableException,gradName); } } int newPrimIndex = UnifyMaximumValue(primIndex); if (primIndex >= 0 && newPrimIndex != primIndex) { // // We shouldn't ever have different orderings for our variables. // EXCEPTION1(InvalidVariableException, primaryVariable); } primIndex = newPrimIndex; int newOpacIndex = UnifyMaximumValue(opacIndex); if (opacIndex >= 0 && newOpacIndex != opacIndex) { // // We shouldn't ever have different orderings for our variables. // EXCEPTION1(InvalidVariableException, atts.GetOpacityVariable()); } opacIndex = newOpacIndex; int newGradIndex = UnifyMaximumValue(gradIndex); if (gradIndex >= 0 && newGradIndex != gradIndex) { // // We shouldn't ever have different orderings for our variables. // EXCEPTION1(InvalidVariableException, gradName); } gradIndex = newGradIndex; // // Set up lighting // avtFlatLighting fl; avtLightingModel *lm = &fl; double gradMax = 0.0, lightingPower = 1.0; if (atts.GetLowGradientLightingReduction() != VolumeAttributes::Off) { gradMax = atts.GetLowGradientLightingClampValue(); if (atts.GetLowGradientLightingClampFlag() == false) { double gradRange[2] = {0,0}; GetDataExtents(gradRange, gradName); gradMax = gradRange[1]; } switch (atts.GetLowGradientLightingReduction()) { case VolumeAttributes::Lowest: lightingPower = 1./16.; break; case VolumeAttributes::Lower: lightingPower = 1./8.; break; case VolumeAttributes::Low: lightingPower = 1./4.; break; case VolumeAttributes::Medium: lightingPower = 1./2.; break; case VolumeAttributes::High: lightingPower = 1.; break; case VolumeAttributes::Higher: lightingPower = 2.; break; case VolumeAttributes::Highest: lightingPower = 4.; break; default: break; } } avtPhong phong(gradMax, lightingPower); if (atts.GetLightingFlag()) { lm = &phong; } else { lm = &fl; } avtOpacityMap *om2 = NULL; if (primIndex == opacIndex) { // Note that we are forcing the color variables range onto the // opacity variable. om2 = &om; } else { om2 = new avtOpacityMap(256); om2->SetTable(vtf, 256, atts.GetOpacityAttenuation()); double range[2]; bool artificialMin = atts.GetUseOpacityVarMin(); bool artificialMax = atts.GetUseOpacityVarMax(); if (!artificialMin || !artificialMax) { InputSetActiveVariable(atts.GetOpacityVariable().c_str()); avtDatasetExaminer::GetDataExtents(input, range); UnifyMinMax(range, 2); InputSetActiveVariable(primaryVariable); } range[0] = (artificialMin ? atts.GetOpacityVarMin() : range[0]); range[1] = (artificialMax ? atts.GetOpacityVarMax() : range[1]); om2->SetMin(range[0]); om2->SetMax(range[1]); // LEAK!! } avtCompositeRF *compositeRF = new avtCompositeRF(lm, &om, om2); if (atts.GetRendererType() == VolumeAttributes::RayCasting && atts.GetSampling() == VolumeAttributes::Trilinear){ compositeRF->SetTrilinearSampling(true); double *matProp = atts.GetMaterialProperties(); double materialPropArray[4]; materialPropArray[0] = matProp[0]; materialPropArray[1] = matProp[1]; materialPropArray[2] = matProp[2]; materialPropArray[3] = matProp[3]; compositeRF->SetMaterial(materialPropArray); } else compositeRF->SetTrilinearSampling(false); avtIntegrationRF *integrateRF = new avtIntegrationRF(lm); compositeRF->SetColorVariableIndex(primIndex); compositeRF->SetOpacityVariableIndex(opacIndex); if (atts.GetLightingFlag()) compositeRF->SetGradientVariableIndex(gradIndex); integrateRF->SetPrimaryVariableIndex(primIndex); integrateRF->SetRange(range[0], range[1]); if (atts.GetSampling() == VolumeAttributes::KernelBased) { software->SetKernelBasedSampling(true); compositeRF->SetWeightVariableIndex(count); } if (atts.GetRendererType() == VolumeAttributes::RayCasting && atts.GetSampling() == VolumeAttributes::Trilinear) software->SetTrilinear(true); else software->SetTrilinear(false); if (atts.GetRendererType() == VolumeAttributes::RayCastingIntegration) software->SetRayFunction(integrateRF); else software->SetRayFunction(compositeRF); software->SetSamplesPerRay(atts.GetSamplesPerRay()); const int *size = window.GetSize(); software->SetScreen(size[0], size[1]); const View3DAttributes &view = window.GetView3D(); avtViewInfo vi; CreateViewInfoFromViewAttributes(vi, view); avtDataObject_p inputData = GetInput(); int width_,height_,depth_; if (GetLogicalBounds(inputData, width_,height_,depth_)) { // if we have logical bounds, compute the slices automatically double viewDirection[3]; int numSlices; viewDirection[0] = (view.GetViewNormal()[0] > 0)? view.GetViewNormal()[0]: -view.GetViewNormal()[0]; viewDirection[1] = (view.GetViewNormal()[1] > 0)? view.GetViewNormal()[1]: -view.GetViewNormal()[1]; viewDirection[2] = (view.GetViewNormal()[2] > 0)? view.GetViewNormal()[2]: -view.GetViewNormal()[2]; numSlices = (width_*viewDirection[0] + height_*viewDirection[1] + depth_*viewDirection[2]) * atts.GetRendererSamples(); if (atts.GetRendererType() == VolumeAttributes::RayCasting && atts.GetSampling() == VolumeAttributes::Trilinear) software->SetSamplesPerRay(numSlices); } software->SetView(vi); if (atts.GetRendererType() == VolumeAttributes::RayCastingIntegration) { integrateRF->SetDistance(view.GetFarPlane()-view.GetNearPlane()); integrateRF->SetWindowSize(size[0], size[1]); } double view_dir[3]; view_dir[0] = vi.focus[0] - vi.camera[0]; view_dir[1] = vi.focus[1] - vi.camera[1]; view_dir[2] = vi.focus[2] - vi.camera[2]; double mag = sqrt(view_dir[0]*view_dir[0] + view_dir[1]*view_dir[1] + view_dir[2]*view_dir[2]); if (mag != 0.) // only 0 if focus and camera are the same { view_dir[0] /= mag; view_dir[1] /= mag; view_dir[2] /= mag; } lm->SetViewDirection(view_dir); lm->SetViewUp(vi.viewUp); lm->SetLightInfo(window.GetLights()); const RenderingAttributes &render_atts = window.GetRenderAtts(); if (render_atts.GetSpecularFlag()) { lm->SetSpecularInfo(render_atts.GetSpecularFlag(), render_atts.GetSpecularCoeff(), render_atts.GetSpecularPower()); } // // Set the volume renderer's background color and mode from the // window attributes. // software->SetBackgroundMode(window.GetBackgroundMode()); software->SetBackgroundColor(window.GetBackground()); software->SetGradientBackgroundColors(window.GetGradBG1(), window.GetGradBG2()); // // We have to set up a sample point "arbitrator" to allow small cells // to be included in the final picture. // avtOpacityMapSamplePointArbitrator arb(om2, opacIndex); avtRay::SetArbitrator(&arb); // // Do the funny business to force an update. // avtDataObject_p dob = software->GetOutput(); dob->Update(GetGeneralContract()); if (atts.GetRendererType() == VolumeAttributes::RayCastingIntegration) integrateRF->OutputRawValues("integration.data"); // // Free up some memory and clean up. // delete software; avtRay::SetArbitrator(NULL); delete compositeRF; delete integrateRF; // // Copy the output of the volume renderer to our output. // avtImage_p output; CopyTo(output, dob); return output; }
avtImage_p avtVolumeFilter::RenderImageRaycastingSLIVR(avtImage_p opaque_image, const WindowAttributes &window) { // // We need to create a dummy pipeline with the volume renderer that we // can force to execute within our "Execute". Start with the source. // avtSourceFromAVTDataset termsrc(GetTypedInput()); // // Set up the volume renderer. // avtRayTracer *software = new avtRayTracer; software->SetInput(termsrc.GetOutput()); software->InsertOpaqueImage(opaque_image); unsigned char vtf[4*256]; atts.GetTransferFunction(vtf); avtOpacityMap om(256); om.SetTableFloat(vtf, 256, atts.GetOpacityAttenuation()*2.0 - 1.0, atts.GetRendererSamples()); double actualRange[2]; bool artificialMin = atts.GetUseColorVarMin(); bool artificialMax = atts.GetUseColorVarMax(); if (!artificialMin || !artificialMax) { GetDataExtents(actualRange, primaryVariable); UnifyMinMax(actualRange, 2); } double range[2]; range[0] = (artificialMin ? atts.GetColorVarMin() : actualRange[0]); range[1] = (artificialMax ? atts.GetColorVarMax() : actualRange[1]); if (atts.GetScaling() == VolumeAttributes::Log) { if (artificialMin) if (range[0] > 0) range[0] = log10(range[0]); if (artificialMax) if (range[1] > 0) range[1] = log10(range[1]); } else if (atts.GetScaling() == VolumeAttributes::Skew) { if (artificialMin) { double newMin = vtkSkewValue(range[0], range[0], range[1], atts.GetSkewFactor()); range[0] = newMin; } if (artificialMax) { double newMax = vtkSkewValue(range[1], range[0], range[1], atts.GetSkewFactor()); range[1] = newMax; } } om.SetMin(range[0]); om.SetMax(range[1]); // // Determine which variables to use and tell the ray function. // VarList vl; avtDataset_p input = GetTypedInput(); avtDatasetExaminer::GetVariableList(input, vl); int primIndex = -1; int opacIndex = -1; int count = 0; char gradName[128]; const char *gradvar = atts.GetOpacityVariable().c_str(); if (strcmp(gradvar, "default") == 0) gradvar = primaryVariable; // This name is explicitly sent to the avtGradientExpression in // the avtVolumePlot. SNPRINTF(gradName, 128, "_%s_gradient", gradvar); for (int i = 0 ; i < vl.nvars ; i++) { if ((strstr(vl.varnames[i].c_str(), "vtk") != NULL) && (strstr(vl.varnames[i].c_str(), "avt") != NULL)) continue; if (vl.varnames[i] == primaryVariable) { primIndex = count; } if (vl.varnames[i] == atts.GetOpacityVariable()) { opacIndex = count; } // if (vl.varnames[i] == gradName) // { // gradIndex = count; // } count += vl.varsizes[i]; } if (primIndex == -1) { if (vl.nvars <= 0) { debug1 << "Could not locate primary variable " << primaryVariable << ", assuming that we are running " << "in parallel and have more processors than domains." << endl; } else { EXCEPTION1(InvalidVariableException, primaryVariable); } } if (opacIndex == -1) { if (atts.GetOpacityVariable() == "default") { opacIndex = primIndex; } else if (vl.nvars <= 0) { debug1 << "Could not locate opacity variable " << atts.GetOpacityVariable().c_str() << ", assuming that we " << "are running in parallel and have more processors " << "than domains." << endl; } else { EXCEPTION1(InvalidVariableException,atts.GetOpacityVariable()); } } // // Set up lighting // avtFlatLighting fl; avtLightingModel *lm = &fl; if (atts.GetLightingFlag()) software->SetLighting(true); else software->SetLighting(false); avtCompositeRF *compositeRF = new avtCompositeRF(lm, &om, &om); double *matProp = atts.GetMaterialProperties(); double materialPropArray[4]; materialPropArray[0] = matProp[0]; materialPropArray[1] = matProp[1]; materialPropArray[2] = matProp[2]; materialPropArray[3] = matProp[3]; software->SetMatProperties(materialPropArray); software->SetRayCastingSLIVR(true); software->SetTrilinear(false); software->SetTransferFn(&om); software->SetRayFunction(compositeRF); // unsure about this one. RayFunction seems important software->SetSamplesPerRay(atts.GetSamplesPerRay()); const int *size = window.GetSize(); software->SetScreen(size[0], size[1]); const View3DAttributes &view = window.GetView3D(); avtViewInfo vi; CreateViewInfoFromViewAttributes(vi, view); avtDataObject_p inputData = GetInput(); int width_,height_,depth_; if (GetLogicalBounds(inputData, width_,height_,depth_)) { double viewDirection[3]; int numSlices; viewDirection[0] = (view.GetViewNormal()[0] > 0)? view.GetViewNormal()[0]: -view.GetViewNormal()[0]; viewDirection[1] = (view.GetViewNormal()[1] > 0)? view.GetViewNormal()[1]: -view.GetViewNormal()[1]; viewDirection[2] = (view.GetViewNormal()[2] > 0)? view.GetViewNormal()[2]: -view.GetViewNormal()[2]; numSlices = (width_*viewDirection[0] + height_*viewDirection[1] + depth_*viewDirection[2]) * atts.GetRendererSamples(); software->SetSamplesPerRay(numSlices); debug5 << "RayCastingSLIVR - slices: "<< numSlices << " : " << width_ << " , " << height_ << " , " << depth_ << endl; } software->SetView(vi); double view_dir[3]; view_dir[0] = vi.focus[0] - vi.camera[0]; view_dir[1] = vi.focus[1] - vi.camera[1]; view_dir[2] = vi.focus[2] - vi.camera[2]; double mag = sqrt(view_dir[0]*view_dir[0] + view_dir[1]*view_dir[1] + view_dir[2]*view_dir[2]); if (mag != 0.) // only 0 if focus and camera are the same { view_dir[0] /= mag; view_dir[1] /= mag; view_dir[2] /= mag; } software->SetViewDirection(view_dir); software->SetViewUp(vi.viewUp); double tempLightDir[3]; tempLightDir[0] = ((window.GetLights()).GetLight(0)).GetDirection()[0]; tempLightDir[1] = ((window.GetLights()).GetLight(0)).GetDirection()[1]; tempLightDir[2] = ((window.GetLights()).GetLight(0)).GetDirection()[2]; software->SetLightDirection(tempLightDir); vtkCamera *camera = vtkCamera::New(); vi.SetCameraFromView(camera); vtkMatrix4x4 *cameraMatrix = camera->GetViewTransformMatrix(); double modelViewMatrix[16]; modelViewMatrix[0] = cameraMatrix->GetElement(0,0); modelViewMatrix[1] = cameraMatrix->GetElement(0,1); modelViewMatrix[2] = cameraMatrix->GetElement(0,2); modelViewMatrix[3] = cameraMatrix->GetElement(0,3); modelViewMatrix[4] = cameraMatrix->GetElement(1,0); modelViewMatrix[5] = cameraMatrix->GetElement(1,1); modelViewMatrix[6] = cameraMatrix->GetElement(1,2); modelViewMatrix[7] = cameraMatrix->GetElement(1,3); modelViewMatrix[8] = cameraMatrix->GetElement(2,0); modelViewMatrix[9] = cameraMatrix->GetElement(2,1); modelViewMatrix[10] = cameraMatrix->GetElement(2,2); modelViewMatrix[11] = cameraMatrix->GetElement(2,3); modelViewMatrix[12] = cameraMatrix->GetElement(3,0); modelViewMatrix[13] = cameraMatrix->GetElement(3,1); modelViewMatrix[14] = cameraMatrix->GetElement(3,2); modelViewMatrix[15] = cameraMatrix->GetElement(3,3); software->SetModelViewMatrix(modelViewMatrix); // // Set the volume renderer's background color and mode from the // window attributes. // software->SetBackgroundMode(window.GetBackgroundMode()); software->SetBackgroundColor(window.GetBackground()); software->SetGradientBackgroundColors(window.GetGradBG1(), window.GetGradBG2()); // // Do the funny business to force an update. ... and called avtDataObject // avtDataObject_p dob = software->GetOutput(); dob->Update(GetGeneralContract()); // // Free up some memory and clean up. // delete software; avtRay::SetArbitrator(NULL); delete compositeRF; // // Copy the output of the volume renderer to our output. // avtImage_p output; CopyTo(output, dob); return output; }