From 9332609f5c6365ea66c2e1ace89471d81464612c Mon Sep 17 00:00:00 2001 From: ouv Date: Mon, 18 Jun 2012 09:46:42 +0000 Subject: [PATCH] Class VTKViewer_Glyph3D (for GUITHARE issue 0001112: External 20480: evolution 3D Layers). --- src/VTKViewer/Makefile.am | 2 + src/VTKViewer/VTKViewer_Glyph3D.cxx | 638 ++++++++++++++++++++++++++++ src/VTKViewer/VTKViewer_Glyph3D.h | 61 +++ 3 files changed, 701 insertions(+) create mode 100644 src/VTKViewer/VTKViewer_Glyph3D.cxx create mode 100644 src/VTKViewer/VTKViewer_Glyph3D.h diff --git a/src/VTKViewer/Makefile.am b/src/VTKViewer/Makefile.am index 567d46e76..dda59b7f3 100755 --- a/src/VTKViewer/Makefile.am +++ b/src/VTKViewer/Makefile.am @@ -49,6 +49,7 @@ salomeinclude_HEADERS = \ VTKViewer_Functor.h \ VTKViewer_MergeFilter.h \ VTKViewer_PassThroughFilter.h \ + VTKViewer_Glyph3D.h \ vtkArcSource.h dist_libVTKViewer_la_SOURCES = \ @@ -73,6 +74,7 @@ dist_libVTKViewer_la_SOURCES = \ VTKViewer_ViewWindow.cxx \ VTKViewer_MergeFilter.cxx \ VTKViewer_PassThroughFilter.cxx \ + VTKViewer_Glyph3D.cxx \ vtkArcSource.cxx MOC_FILES = \ diff --git a/src/VTKViewer/VTKViewer_Glyph3D.cxx b/src/VTKViewer/VTKViewer_Glyph3D.cxx new file mode 100644 index 000000000..3777c7f75 --- /dev/null +++ b/src/VTKViewer/VTKViewer_Glyph3D.cxx @@ -0,0 +1,638 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// This library 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 2.1 of the License. +// +// This library 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 Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "VTKViewer_Glyph3D.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +vtkStandardNewMacro(VTKViewer_Glyph3D); + +//---------------------------------------------------------------------------- +// Construct object with scaling on, scaling mode is by scalar value, +// scale factor = 1.0, the range is (0,1), orient geometry is on, and +// orientation is by vector. Clamping and indexing are turned off. No +// initial sources are defined. +VTKViewer_Glyph3D::VTKViewer_Glyph3D() +{ + this->FillCellData = 0; +} + +//---------------------------------------------------------------------------- +VTKViewer_Glyph3D::~VTKViewer_Glyph3D() +{ + if (this->PointIdsName) + { + delete []PointIdsName; + } +} + +//---------------------------------------------------------------------------- +int VTKViewer_Glyph3D::RequestData( + vtkInformation *vtkNotUsed(request), + vtkInformationVector **inputVector, + vtkInformationVector *outputVector) +{ + // get the info objects + vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); + vtkInformation *outInfo = outputVector->GetInformationObject(0); + + // get the input and ouptut + vtkDataSet *input = vtkDataSet::SafeDownCast( + inInfo->Get(vtkDataObject::DATA_OBJECT())); + vtkPolyData *output = vtkPolyData::SafeDownCast( + outInfo->Get(vtkDataObject::DATA_OBJECT())); + + vtkPointData *pd; + vtkDataArray *inSScalars; // Scalars for Scaling + vtkDataArray *inCScalars; // Scalars for Coloring + vtkDataArray *inVectors; + int requestedGhostLevel; + unsigned char* inGhostLevels=0; + vtkDataArray *inNormals, *sourceNormals = NULL; + vtkDataArray *sourceTCoords = NULL; + vtkIdType numPts, numSourcePts, numSourceCells, inPtId, i; + int index; + vtkPoints *sourcePts = NULL; + vtkPoints *newPts; + vtkDataArray *newScalars=NULL; + vtkDataArray *newVectors=NULL; + vtkDataArray *newNormals=NULL; + vtkDataArray *newTCoords = NULL; + double x[3], v[3], vNew[3], s = 0.0, vMag = 0.0, value, tc[3]; + vtkTransform *trans = vtkTransform::New(); + vtkCell *cell; + vtkIdList *cellPts; + int npts; + vtkIdList *pts; + vtkIdType ptIncr, cellIncr, cellId; + int haveVectors, haveNormals, haveTCoords = 0; + double scalex,scaley,scalez, den; + vtkPointData *outputPD = output->GetPointData(); + vtkCellData* outputCD = output->GetCellData(); + int numberOfSources = this->GetNumberOfInputConnections(1); + vtkPolyData *defaultSource = NULL; + vtkIdTypeArray *pointIds=0; + vtkPolyData *source = 0; + + vtkDebugMacro(<<"Generating glyphs"); + + pts = vtkIdList::New(); + pts->Allocate(VTK_CELL_SIZE); + + pd = input->GetPointData(); + inSScalars = this->GetInputArrayToProcess(0,inputVector); + inVectors = this->GetInputArrayToProcess(1,inputVector); + inNormals = this->GetInputArrayToProcess(2,inputVector); + inCScalars = this->GetInputArrayToProcess(3,inputVector); + if (inCScalars == NULL) + { + inCScalars = inSScalars; + } + + vtkDataArray* temp = 0; + if (pd) + { + temp = pd->GetArray("vtkGhostLevels"); + } + if ( (!temp) || (temp->GetDataType() != VTK_UNSIGNED_CHAR) + || (temp->GetNumberOfComponents() != 1)) + { + vtkDebugMacro("No appropriate ghost levels field available."); + } + else + { + inGhostLevels = ((vtkUnsignedCharArray*)temp)->GetPointer(0); + } + + requestedGhostLevel = + outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS()); + + numPts = input->GetNumberOfPoints(); + if (numPts < 1) + { + vtkDebugMacro(<<"No points to glyph!"); + pts->Delete(); + trans->Delete(); + return 1; + } + + // Check input for consistency + // + if ( (den = this->Range[1] - this->Range[0]) == 0.0 ) + { + den = 1.0; + } + if ( this->VectorMode != VTK_VECTOR_ROTATION_OFF && + ((this->VectorMode == VTK_USE_VECTOR && inVectors != NULL) || + (this->VectorMode == VTK_USE_NORMAL && inNormals != NULL)) ) + { + haveVectors = 1; + } + else + { + haveVectors = 0; + } + + if ( (this->IndexMode == VTK_INDEXING_BY_SCALAR && !inSScalars) || + (this->IndexMode == VTK_INDEXING_BY_VECTOR && + ((!inVectors && this->VectorMode == VTK_USE_VECTOR) || + (!inNormals && this->VectorMode == VTK_USE_NORMAL))) ) + { + if ( this->GetSource(0, inputVector[1]) == NULL ) + { + vtkErrorMacro(<<"Indexing on but don't have data to index with"); + pts->Delete(); + trans->Delete(); + return 1; + } + else + { + vtkWarningMacro(<<"Turning indexing off: no data to index with"); + this->IndexMode = VTK_INDEXING_OFF; + } + } + + // Allocate storage for output PolyData + // + outputPD->CopyVectorsOff(); + outputPD->CopyNormalsOff(); + outputPD->CopyTCoordsOff(); + + if (!this->GetSource(0, inputVector[1])) + { + defaultSource = vtkPolyData::New(); + defaultSource->Allocate(); + vtkPoints *defaultPoints = vtkPoints::New(); + defaultPoints->Allocate(6); + defaultPoints->InsertNextPoint(0, 0, 0); + defaultPoints->InsertNextPoint(1, 0, 0); + vtkIdType defaultPointIds[2]; + defaultPointIds[0] = 0; + defaultPointIds[1] = 1; + defaultSource->SetPoints(defaultPoints); + defaultSource->InsertNextCell(VTK_LINE, 2, defaultPointIds); + defaultSource->SetUpdateExtent(0, 1, 0); + this->SetSource(defaultSource); + defaultSource->Delete(); + defaultSource = NULL; + defaultPoints->Delete(); + defaultPoints = NULL; + } + + if ( this->IndexMode != VTK_INDEXING_OFF ) + { + pd = NULL; + haveNormals = 1; + for (numSourcePts=numSourceCells=i=0; i < numberOfSources; i++) + { + source = this->GetSource(i, inputVector[1]); + if ( source != NULL ) + { + if (source->GetNumberOfPoints() > numSourcePts) + { + numSourcePts = source->GetNumberOfPoints(); + } + if (source->GetNumberOfCells() > numSourceCells) + { + numSourceCells = source->GetNumberOfCells(); + } + if ( !(sourceNormals = source->GetPointData()->GetNormals()) ) + { + haveNormals = 0; + } + } + } + } + else + { + source = this->GetSource(0, inputVector[1]); + sourcePts = source->GetPoints(); + numSourcePts = sourcePts->GetNumberOfPoints(); + numSourceCells = source->GetNumberOfCells(); + + sourceNormals = source->GetPointData()->GetNormals(); + if ( sourceNormals ) + { + haveNormals = 1; + } + else + { + haveNormals = 0; + } + + sourceTCoords = source->GetPointData()->GetTCoords(); + if (sourceTCoords) + { + haveTCoords = 1; + } + else + { + haveTCoords = 0; + } + + // Prepare to copy output. + pd = input->GetPointData(); + outputPD->CopyAllocate(pd,numPts*numSourcePts); + if (this->FillCellData) + { + outputCD->CopyAllocate(pd,numPts*numSourceCells); + } + } + + newPts = vtkPoints::New(); + newPts->Allocate(numPts*numSourcePts); + if ( this->GeneratePointIds ) + { + pointIds = vtkIdTypeArray::New(); + pointIds->SetName(this->PointIdsName); + pointIds->Allocate(numPts*numSourcePts); + outputPD->AddArray(pointIds); + pointIds->Delete(); + } + if ( this->ColorMode == VTK_COLOR_BY_SCALAR && inCScalars ) + { + newScalars = inCScalars->NewInstance(); + newScalars->SetNumberOfComponents(inCScalars->GetNumberOfComponents()); + newScalars->Allocate(inCScalars->GetNumberOfComponents()*numPts*numSourcePts); + newScalars->SetName(inCScalars->GetName()); + } + else if ( (this->ColorMode == VTK_COLOR_BY_SCALE) && inSScalars) + { + newScalars = vtkFloatArray::New(); + newScalars->Allocate(numPts*numSourcePts); + newScalars->SetName("GlyphScale"); + if (this->ScaleMode == VTK_SCALE_BY_SCALAR) + { + newScalars->SetName(inSScalars->GetName()); + } + } + else if ( (this->ColorMode == VTK_COLOR_BY_VECTOR) && haveVectors) + { + newScalars = vtkFloatArray::New(); + newScalars->Allocate(numPts*numSourcePts); + newScalars->SetName("VectorMagnitude"); + } + if ( haveVectors ) + { + newVectors = vtkFloatArray::New(); + newVectors->SetNumberOfComponents(3); + newVectors->Allocate(3*numPts*numSourcePts); + newVectors->SetName("GlyphVector"); + } + if ( haveNormals ) + { + newNormals = vtkFloatArray::New(); + newNormals->SetNumberOfComponents(3); + newNormals->Allocate(3*numPts*numSourcePts); + newNormals->SetName("Normals"); + } + if (haveTCoords) + { + newTCoords = vtkFloatArray::New(); + int numComps = sourceTCoords->GetNumberOfComponents(); + newTCoords->SetNumberOfComponents(numComps); + newTCoords->Allocate(numComps*numPts*numSourcePts); + newTCoords->SetName("TCoords"); + } + + // Setting up for calls to PolyData::InsertNextCell() + if (this->IndexMode != VTK_INDEXING_OFF ) + { + output->Allocate(3*numPts*numSourceCells,numPts*numSourceCells); + } + else + { + output->Allocate(this->GetSource(0, inputVector[1]), + 3*numPts*numSourceCells, numPts*numSourceCells); + } + + // Traverse all Input points, transforming Source points and copying + // point attributes. + // + ptIncr=0; + cellIncr=0; + for (inPtId=0; inPtId < numPts; inPtId++) + { + scalex = scaley = scalez = 1.0; + if ( ! (inPtId % 10000) ) + { + this->UpdateProgress ((double)inPtId/numPts); + if (this->GetAbortExecute()) + { + break; + } + } + + // Get the scalar and vector data + if ( inSScalars ) + { + s = inSScalars->GetComponent(inPtId, 0); + if ( this->ScaleMode == VTK_SCALE_BY_SCALAR || + this->ScaleMode == VTK_DATA_SCALING_OFF ) + { + scalex = scaley = scalez = s; + } + } + + if ( haveVectors ) + { + if ( this->VectorMode == VTK_USE_NORMAL ) + { + inNormals->GetTuple(inPtId, v); + } + else + { + inVectors->GetTuple(inPtId, v); + } + vMag = vtkMath::Norm(v); + if ( this->ScaleMode == VTK_SCALE_BY_VECTORCOMPONENTS ) + { + scalex = v[0]; + scaley = v[1]; + scalez = v[2]; + } + else if ( this->ScaleMode == VTK_SCALE_BY_VECTOR ) + { + scalex = scaley = scalez = vMag; + } + } + + // Clamp data scale if enabled + if ( this->Clamping ) + { + scalex = (scalex < this->Range[0] ? this->Range[0] : + (scalex > this->Range[1] ? this->Range[1] : scalex)); + scalex = (scalex - this->Range[0]) / den; + scaley = (scaley < this->Range[0] ? this->Range[0] : + (scaley > this->Range[1] ? this->Range[1] : scaley)); + scaley = (scaley - this->Range[0]) / den; + scalez = (scalez < this->Range[0] ? this->Range[0] : + (scalez > this->Range[1] ? this->Range[1] : scalez)); + scalez = (scalez - this->Range[0]) / den; + } + + // Compute index into table of glyphs + if ( this->IndexMode == VTK_INDEXING_OFF ) + { + index = 0; + } + else + { + if ( this->IndexMode == VTK_INDEXING_BY_SCALAR ) + { + value = s; + } + else + { + value = vMag; + } + + index = (int) ((double)(value - this->Range[0]) * numberOfSources / den); + index = (index < 0 ? 0 : + (index >= numberOfSources ? (numberOfSources-1) : index)); + + source = this->GetSource(index, inputVector[1]); + if ( source != NULL ) + { + sourcePts = source->GetPoints(); + sourceNormals = source->GetPointData()->GetNormals(); + numSourcePts = sourcePts->GetNumberOfPoints(); + numSourceCells = source->GetNumberOfCells(); + } + } + + // Make sure we're not indexing into empty glyph + if ( this->GetSource(index, inputVector[1]) == NULL ) + { + continue; + } + + // Check ghost points. + // If we are processing a piece, we do not want to duplicate + // glyphs on the borders. The corrct check here is: + // ghostLevel > 0. I am leaving this over glyphing here because + // it make a nice example (sphereGhost.tcl) to show the + // point ghost levels with the glyph filter. I am not certain + // of the usefullness of point ghost levels over 1, but I will have + // to think about it. + if (inGhostLevels && inGhostLevels[inPtId] > requestedGhostLevel) + { + continue; + } + + if (!this->IsPointVisible(input, inPtId)) + { + continue; + } + + // Now begin copying/transforming glyph + trans->Identity(); + + // Copy all topology (transformation independent) + for (cellId=0; cellId < numSourceCells; cellId++) + { + cell = this->GetSource(index, inputVector[1])->GetCell(cellId); + cellPts = cell->GetPointIds(); + npts = cellPts->GetNumberOfIds(); + for (pts->Reset(), i=0; i < npts; i++) + { + pts->InsertId(i,cellPts->GetId(i) + ptIncr); + } + output->InsertNextCell(cell->GetCellType(),pts); + } + + // translate Source to Input point + input->GetPoint(inPtId, x); + trans->Translate(x[0], x[1], x[2]); + + if ( haveVectors ) + { + // Copy Input vector + for (i=0; i < numSourcePts; i++) + { + newVectors->InsertTuple(i+ptIncr, v); + } + if (this->Orient && (vMag > 0.0)) + { + // if there is no y or z component + if ( v[1] == 0.0 && v[2] == 0.0 ) + { + if (v[0] < 0) //just flip x if we need to + { + trans->RotateWXYZ(180.0,0,1,0); + } + } + else + { + vNew[0] = (v[0]+vMag) / 2.0; + vNew[1] = v[1] / 2.0; + vNew[2] = v[2] / 2.0; + trans->RotateWXYZ((double)180.0,vNew[0],vNew[1],vNew[2]); + } + } + } + + if (haveTCoords) + { + for (i = 0; i < numSourcePts; i++) + { + sourceTCoords->GetTuple(i, tc); + newTCoords->InsertTuple(i+ptIncr, tc); + } + } + + // determine scale factor from scalars if appropriate + // Copy scalar value + if (inSScalars && (this->ColorMode == VTK_COLOR_BY_SCALE)) + { + for (i=0; i < numSourcePts; i++) + { + newScalars->InsertTuple(i+ptIncr, &scalex); // = scaley = scalez + } + } + else if (inCScalars && (this->ColorMode == VTK_COLOR_BY_SCALAR)) + { + for (i=0; i < numSourcePts; i++) + { + outputPD->CopyTuple(inCScalars, newScalars, inPtId, ptIncr+i); + } + } + if (haveVectors && this->ColorMode == VTK_COLOR_BY_VECTOR) + { + for (i=0; i < numSourcePts; i++) + { + newScalars->InsertTuple(i+ptIncr, &vMag); + } + } + + // scale data if appropriate + if ( this->Scaling ) + { + if ( this->ScaleMode == VTK_DATA_SCALING_OFF ) + { + scalex = scaley = scalez = this->ScaleFactor; + } + else + { + scalex *= this->ScaleFactor; + scaley *= this->ScaleFactor; + scalez *= this->ScaleFactor; + } + + if ( scalex == 0.0 ) + { + scalex = 1.0e-10; + } + if ( scaley == 0.0 ) + { + scaley = 1.0e-10; + } + if ( scalez == 0.0 ) + { + scalez = 1.0e-10; + } + trans->Scale(scalex,scaley,scalez); + } + + // multiply points and normals by resulting matrix + trans->TransformPoints(sourcePts,newPts); + + if ( haveNormals ) + { + trans->TransformNormals(sourceNormals,newNormals); + } + + // Copy point data from source (if possible) + if ( pd ) + { + for (i=0; i < numSourcePts; i++) + { + outputPD->CopyData(pd,inPtId,ptIncr+i); + } + if (this->FillCellData) + { + for (i=0; i < numSourceCells; i++) + { + outputCD->CopyData(pd,inPtId,cellIncr+i); + } + } + } + + // If point ids are to be generated, do it here + if ( this->GeneratePointIds ) + { + for (i=0; i < numSourcePts; i++) + { + pointIds->InsertNextValue(inPtId); + } + } + + ptIncr += numSourcePts; + cellIncr += numSourceCells; + } + + // Update ourselves and release memory + // + output->SetPoints(newPts); + newPts->Delete(); + + if (newScalars) + { + int idx = outputPD->AddArray(newScalars); + outputPD->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS); + newScalars->Delete(); + } + + if (newVectors) + { + outputPD->SetVectors(newVectors); + newVectors->Delete(); + } + + if (newNormals) + { + outputPD->SetNormals(newNormals); + newNormals->Delete(); + } + + if (newTCoords) + { + outputPD->SetTCoords(newTCoords); + newTCoords->Delete(); + } + + output->Squeeze(); + trans->Delete(); + pts->Delete(); + + return 1; +} diff --git a/src/VTKViewer/VTKViewer_Glyph3D.h b/src/VTKViewer/VTKViewer_Glyph3D.h new file mode 100644 index 000000000..77cc0b0f1 --- /dev/null +++ b/src/VTKViewer/VTKViewer_Glyph3D.h @@ -0,0 +1,61 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// This library 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 2.1 of the License. +// +// This library 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 Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef VTKVIEWER_GLYPH3D_H +#define VTKVIEWER_GLYPH3D_H + +#include "VTKViewer.h" + +#include + +class VTKVIEWER_EXPORT VTKViewer_Glyph3D : public vtkGlyph3D +{ +public: + vtkTypeMacro(VTKViewer_Glyph3D,vtkGlyph3D); + + // Description + // Construct object with scaling on, scaling mode is by scalar value, + // scale factor = 1.0, the range is (0,1), orient geometry is on, and + // orientation is by vector. Clamping and indexing are turned off. No + // initial sources are defined. + static VTKViewer_Glyph3D *New(); + + // Description: + // Enable/disable the generation of cell data as part of the output. + // The cell data at each cell will match the point data of the input + // at the glyphed point. + vtkSetMacro(FillCellData,int); + vtkGetMacro(FillCellData,int); + vtkBooleanMacro(FillCellData,int); + +protected: + VTKViewer_Glyph3D(); + ~VTKViewer_Glyph3D(); + + virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); + //virtual int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *); + //virtual int FillInputPortInformation(int, vtkInformation *); + + int FillCellData; // whether to fill output cell data + +private: + VTKViewer_Glyph3D(const VTKViewer_Glyph3D&); // Not implemented. + void operator=(const VTKViewer_Glyph3D&); // Not implemented. +}; + +#endif -- 2.39.2