/* * Copyright (C) 2005,2006,2007,2008,2009,2010 Thorsten Liebig (Thorsten.Liebig@gmx.de) * * This program 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. * * This program 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 program. If not, see . */ #include "VTKPrimitives.h" #include "vtkRenderer.h" #include "vtkActorCollection.h" #include "vtkPolyDataMapper.h" #include "vtkDoubleArray.h" #include "vtkLODActor.h" #include "vtkActor.h" #include "vtkProperty.h" #include "vtkCamera.h" #include "vtkCubeSource.h" #include "vtkPlaneSource.h" #include "vtkCylinderSource.h" #include "vtkLineSource.h" #include "vtkSphereSource.h" #include "vtkPoints.h" #include "vtkCellArray.h" #include "vtkRotationalExtrusionFilter.h" #include "vtkLinearExtrusionFilter.h" #include "vtkArrowSource.h" #include "vtkSTLReader.h" #include "vtkVectorText.h" #include "vtkFollower.h" #include "vtkTriangleFilter.h" #include "vtkFloatArray.h" #include "vtkPointData.h" #include "vtkTransform.h" #include "vtkTransformPolyDataFilter.h" #include "vtkCollectionIterator.h" #include "vtkConeSource.h" #include "vtkTubeFilter.h" #include "vtkAppendPolyData.h" #include "vtkXMLPolyDataWriter.h" #include "vtkSTLWriter.h" #include "vtkDiskSource.h" #include "vtkPLYWriter.h" #if (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION>=10) || (VTK_MAJOR_VERSION>=6) #include "vtkBooleanOperationPolyDataFilter.h" #endif VTKPrimitives::VTKPrimitives(vtkRenderer *Renderer) { ren = Renderer; ActorColl = vtkActorCollection::New(); m_PolyDataCollection = vtkAppendPolyData::New(); m_ArcDelta = 3.0/180.0*PI; // default of 5° resolution for representing angles } VTKPrimitives::~VTKPrimitives() { ActorColl->InitTraversal(); vtkActor* act=NULL; while ((act=ActorColl->GetNextActor())) { ren->RemoveActor(act); act->Delete(); } ActorColl->Delete(); ActorColl=NULL; if (m_PolyDataCollection) m_PolyDataCollection->Delete(); m_PolyDataCollection=NULL; } VTKPrimitives::VTKPrimitives() { } void VTKPrimitives::AddCube(const double *start, const double *stop, double *dRGB, double dOpacity, const double* tf_matrix) { double coords[6] = {start[0],stop[0],start[1],stop[1],start[2],stop[2]}; double help; int dim=0; //swap start stop if start>stop for (int n=0;n<3;++n) { if (coords[2*n]>coords[2*n+1]) { help=coords[2*n+1]; coords[2*n+1]=coords[2*n]; coords[2*n]=help; } if (coords[2*n]!=coords[2*n+1]) ++dim; } if (dim==0) { cerr << "VTKPrimitives::AddCube: Warning, can't draw a Point Box... skipping" << endl; return; } if (dim==1) return AddLinePoly(coords,2,1,dRGB,dOpacity); AddCube(coords,dRGB,dOpacity,tf_matrix); } void VTKPrimitives::AddCube(double *dCoords, double *dRGB, double dOpacity, const double* tf_matrix) { //create a simple cartesian cube... vtkCubeSource *Source = vtkCubeSource::New(); Source->SetBounds(dCoords); AddPolyData(Source->GetOutputPort(), dRGB, dOpacity, tf_matrix); Source->Delete(); } void VTKPrimitives::AddCylindricalCube(const double *start, const double *stop, double *dRGB, double dOpacity, const double* tf_matrix) { double coords[6] = {start[0],stop[0],start[1],stop[1],start[2],stop[2]}; double help; //swap start stop if start>stop for (int n=0;n<3;++n) { if (coords[2*n]>coords[2*n+1]) { help=coords[2*n+1]; coords[2*n+1]=coords[2*n]; coords[2*n]=help; } } AddCylindricalCube(coords,dRGB,dOpacity,tf_matrix); } void VTKPrimitives::AddCylindricalCube(double *dCoords, double *dRGB, double dOpacity, const double* tf_matrix) { vtkPolyDataAlgorithm* PDSource = NULL; vtkPolyDataAlgorithm* PDFilter = NULL; if ( (dCoords[2]!=dCoords[3]) ) { if ((dCoords[0]!=dCoords[1]) && ((dCoords[4]!=dCoords[5]))) //3D object { double dO[3] = {dCoords[0],dCoords[2],dCoords[4]}; double dP1[3] = {dCoords[0],dCoords[2],dCoords[5]}; double dP2[3] = {dCoords[1],dCoords[2],dCoords[4]}; double out[3]; vtkPlaneSource *Source = vtkPlaneSource::New(); Source->SetOrigin(TransformCylindricalCoords(dO,out)); Source->SetPoint1(TransformCylindricalCoords(dP1,out)); Source->SetPoint2(TransformCylindricalCoords(dP2,out)); PDSource = Source; } else if (dCoords[4]!=dCoords[5]) // alpha-z plane { double dP1[3] = {dCoords[0],dCoords[2],dCoords[4]}; double dP2[3] = {dCoords[0],dCoords[2],dCoords[5]}; double out[3]; vtkLineSource *Source = vtkLineSource::New(); Source->SetPoint1(TransformCylindricalCoords(dP1,out)); Source->SetPoint2(TransformCylindricalCoords(dP2,out)); PDSource = Source; } else if (dCoords[0]!=dCoords[1]) // alpha-r plane { double dP1[3] = {dCoords[0],dCoords[2],dCoords[4]}; double dP2[3] = {dCoords[1],dCoords[2],dCoords[4]}; double out[3]; vtkLineSource *Source = vtkLineSource::New(); Source->SetPoint1(TransformCylindricalCoords(dP1,out)); Source->SetPoint2(TransformCylindricalCoords(dP2,out)); PDSource = Source; } else //line in a-direction { double out[6]; return AddLinePoly(TransformCylindricalCoords(dCoords,out,2),2,1,dRGB,dOpacity); } if (PDSource==NULL) return; vtkRotationalExtrusionFilter *extrude = vtkRotationalExtrusionFilter::New(); #if VTK_MAJOR_VERSION>=6 extrude->SetInputConnection(PDSource->GetOutputPort()); #else extrude->SetInput(PDSource->GetOutput()); #endif int nrSteps = ceil(fabs(dCoords[3]-dCoords[2])/m_ArcDelta); extrude->SetResolution(nrSteps); extrude->SetAngle( (dCoords[3]-dCoords[2])*180/PI ); PDFilter = extrude; } else //rz-plane or line { if (dCoords[0]==dCoords[1]) //line in z-direction { double out[6]; return AddLinePoly(TransformCylindricalCoords(dCoords,out,2),2,1,dRGB,dOpacity); } if (dCoords[4]==dCoords[5]) //line in r-direction { double out[6]; return AddLinePoly(TransformCylindricalCoords(dCoords,out,2),2,1,dRGB,dOpacity); } //rz-plane double dO[3] = {dCoords[0],dCoords[2],dCoords[4]}; double dP1[3] = {dCoords[0],dCoords[2],dCoords[5]}; double dP2[3] = {dCoords[1],dCoords[2],dCoords[4]}; double out[3]; vtkPlaneSource *Source = vtkPlaneSource::New(); Source->SetOrigin(TransformCylindricalCoords(dO,out)); Source->SetPoint1(TransformCylindricalCoords(dP1,out)); Source->SetPoint2(TransformCylindricalCoords(dP2,out)); PDFilter = Source; } if (PDFilter==NULL) return; AddPolyData(PDFilter->GetOutputPort(), dRGB, dOpacity, tf_matrix); if (PDSource) PDSource->Delete(); PDFilter->Delete(); } void VTKPrimitives::AddPlane(double *dOrigin, double* dP1, double* dP2, double *dRGB, double dOpacity, const double* tf_matrix) { double out[3]; vtkPlaneSource *Source = vtkPlaneSource::New(); Source->SetOrigin(TransformCylindricalCoords(dOrigin,out)); Source->SetPoint1(TransformCylindricalCoords(dP1,out)); Source->SetPoint2(TransformCylindricalCoords(dP2,out)); AddPolyData(Source->GetOutputPort(), dRGB, dOpacity, tf_matrix); Source->Delete(); } void VTKPrimitives::AddDisc(double *dCoords, unsigned int uiQtyCoords, double *dRGB, double dOpacity, const double* tf_matrix) { unsigned int i=0,j=0;//,h=0;//,k=0; vtkPoints *points = vtkPoints::New(); vtkCellArray *poly = vtkCellArray::New(); vtkPolyData *profile = vtkPolyData::New(); for (i=0; iInsertPoint(j++,dCoords[i],dCoords[uiQtyCoords+i],dCoords[2*uiQtyCoords+i]);//0 points->InsertPoint(j++,dCoords[i+1],dCoords[uiQtyCoords+i],dCoords[2*uiQtyCoords+i]);//1 points->InsertPoint(j++,dCoords[i+1],dCoords[uiQtyCoords+i+1],dCoords[2*uiQtyCoords+i]);//2 points->InsertPoint(j++,dCoords[i],dCoords[uiQtyCoords+i+1],dCoords[2*uiQtyCoords+i]);//3 points->InsertPoint(j++,dCoords[i],dCoords[uiQtyCoords+i],dCoords[2*uiQtyCoords+i+1]);//4 points->InsertPoint(j++,dCoords[i+1],dCoords[uiQtyCoords+i],dCoords[2*uiQtyCoords+i+1]);//5 points->InsertPoint(j++,dCoords[i+1],dCoords[uiQtyCoords+i+1],dCoords[2*uiQtyCoords+i+1]);//6 points->InsertPoint(j++,dCoords[i],dCoords[uiQtyCoords+i+1],dCoords[2*uiQtyCoords+i+1]);//7 poly->InsertNextCell(4);poly->InsertCellPoint(0+i*4);poly->InsertCellPoint(1+i*4);poly->InsertCellPoint(2+i*4);poly->InsertCellPoint(3+i*4); poly->InsertNextCell(4);poly->InsertCellPoint(4+i*4);poly->InsertCellPoint(5+i*4);poly->InsertCellPoint(6+i*4);poly->InsertCellPoint(7+i*4); poly->InsertNextCell(4);poly->InsertCellPoint(0+i*4);poly->InsertCellPoint(1+i*4);poly->InsertCellPoint(5+i*4);poly->InsertCellPoint(4+i*4); poly->InsertNextCell(4);poly->InsertCellPoint(1+i*4);poly->InsertCellPoint(2+i*4);poly->InsertCellPoint(6+i*4);poly->InsertCellPoint(5+i*4); poly->InsertNextCell(4);poly->InsertCellPoint(2+i*4);poly->InsertCellPoint(3+i*4);poly->InsertCellPoint(7+i*4);poly->InsertCellPoint(6+i*4); poly->InsertNextCell(4);poly->InsertCellPoint(3+i*4);poly->InsertCellPoint(0+i*4);poly->InsertCellPoint(4+i*4);poly->InsertCellPoint(7+i*4); //for (h=j-8;hInsertTuple1(h,h%8); // not in use jet //fprintf(stderr,"."); } profile->SetPoints(points); profile->SetPolys(poly); AddPolyData(profile, dRGB, dOpacity, tf_matrix); points->Delete(); poly->Delete(); profile->Delete(); } void VTKPrimitives::AddClosedPoly(double *dCoords, unsigned int uiQtyCoords, double *dExtrusionVector, double *dRGB, double dOpacity, const double* tf_matrix) { //complete unsigned int i=0; vtkPoints *points = vtkPoints::New(); vtkCellArray *poly = vtkCellArray::New(); vtkPolyData *profile = vtkPolyData::New(); vtkLinearExtrusionFilter *extrude = vtkLinearExtrusionFilter::New(); for (i=0; iInsertPoint(i,dCoords[i],dCoords[uiQtyCoords+i],dCoords[2*uiQtyCoords+i]); poly->InsertNextCell(uiQtyCoords+1); for (i=0; iInsertCellPoint(i); poly->InsertCellPoint(0); profile->SetPoints(points); profile->SetPolys(poly); vtkTriangleFilter *tf = vtkTriangleFilter::New(); #if VTK_MAJOR_VERSION>=6 tf->SetInputData(profile); #else tf->SetInput(profile); #endif extrude->SetInputConnection(tf->GetOutputPort()); extrude->SetExtrusionTypeToVectorExtrusion(); extrude->SetVector(dExtrusionVector); extrude->CappingOn(); AddPolyData(extrude->GetOutputPort(), dRGB, dOpacity, tf_matrix); points->Delete(); poly->Delete(); profile->Delete(); tf->Delete(); extrude->Delete(); } void VTKPrimitives::AddLinePoly(const double *dCoords, unsigned int uiQtyCoords, unsigned int LineWidth, double *dRGB, double dOpacity, const double* tf_matrix) { //complete unsigned int i=0; vtkPoints *points = vtkPoints::New(); vtkCellArray *poly = vtkCellArray::New(); vtkPolyData *profile = vtkPolyData::New(); for (i=0; iInsertPoint(i,dCoords[i],dCoords[uiQtyCoords+i],dCoords[2*uiQtyCoords+i]); for (i=1; iInsertNextCell(2); poly->InsertCellPoint(i-1); poly->InsertCellPoint(i); } profile->SetPoints(points); profile->SetLines(poly); vtkActor* actor = AddPolyData(profile, dRGB, dOpacity, tf_matrix); actor->GetProperty()->SetLineWidth(LineWidth); points->Delete(); poly->Delete(); profile->Delete(); } void VTKPrimitives::AddTubePoly(const double *dCoords, unsigned int uiQtyCoords, double TubeRadius, double *dRGB, double dOpacity, int iResolution, const double* tf_matrix) { //complete unsigned int i=0; vtkPoints *points = vtkPoints::New(); vtkCellArray *poly = vtkCellArray::New(); vtkPolyData *profile = vtkPolyData::New(); for (i=0; iInsertPoint(i,dCoords[i],dCoords[uiQtyCoords+i],dCoords[2*uiQtyCoords+i]); for (i=1; iInsertNextCell(2); poly->InsertCellPoint(i-1); poly->InsertCellPoint(i); } profile->SetPoints(points); profile->SetLines(poly); vtkTubeFilter* m_profileTubes = vtkTubeFilter::New(); m_profileTubes->SetNumberOfSides(iResolution); #if VTK_MAJOR_VERSION>=6 m_profileTubes->SetInputData(profile); #else m_profileTubes->SetInput(profile); #endif m_profileTubes->SetRadius(TubeRadius); AddPolyData(m_profileTubes->GetOutputPort(), dRGB, dOpacity, tf_matrix); points->Delete(); poly->Delete(); profile->Delete(); m_profileTubes->Delete(); } void VTKPrimitives::AddCylinder2(const double *dAxisStart, const double* dAxisStop, float fRadius, double *dRGB, double dOpacity, int iResolution, const double* tf_matrix) { double direction[3] = {dAxisStop[0]-dAxisStart[0],dAxisStop[1]-dAxisStart[1],dAxisStop[2]-dAxisStart[2]}; AddCylinder(dAxisStart,direction,fRadius,dRGB,dOpacity,iResolution,tf_matrix); } void VTKPrimitives::AddCylinder(const double *dCenter, const double *dExtrusionVector, float fRadius, double *dRGB, double dOpacity, int iResolution, const double* tf_matrix) { double alpha=0,beta=0; double length=sqrt( dExtrusionVector[0]*dExtrusionVector[0]+dExtrusionVector[1]*dExtrusionVector[1]+dExtrusionVector[2]*dExtrusionVector[2] ) ; //if (length==0) { fprintf(stderr," Error Cylinder Extrusion Vector ist Zero.. Abort..."); exit(1); } vtkCylinderSource *Source = vtkCylinderSource::New(); vtkTransform *transform = vtkTransform::New(); vtkTransformPolyDataFilter *transformFilter = vtkTransformPolyDataFilter::New(); Source->SetResolution(iResolution); Source->SetRadius(fRadius); Source->SetHeight(length); alpha=VectorAngel(dExtrusionVector[0],sqrt(dExtrusionVector[1]*dExtrusionVector[1]+dExtrusionVector[2]*dExtrusionVector[2]),0,0,1,0); beta=VectorAngel(0,dExtrusionVector[1],dExtrusionVector[2],0,1,0); // cout << alpha << " " << beta << endl; //debuging if (dExtrusionVector[0]>0) alpha=-alpha; if (dExtrusionVector[2]<0) beta=-beta; transform->Translate(dExtrusionVector[0]/2+dCenter[0],dExtrusionVector[1]/2+dCenter[1],dExtrusionVector[2]/2+dCenter[2]); transform->RotateWXYZ(beta,1,0,0); transform->RotateWXYZ(alpha,0,0,1); transform->PostMultiply(); #if VTK_MAJOR_VERSION>=6 transformFilter->SetInputConnection(Source->GetOutputPort()); #else transformFilter->SetInput(Source->GetOutput()); #endif transformFilter->SetTransform(transform); AddPolyData(transformFilter->GetOutputPort(), dRGB, dOpacity, tf_matrix); Source->Delete(); transform->Delete(); transformFilter->Delete(); } void VTKPrimitives::AddCylindricalShell(const double *dAxisStart, const double* dAxisStop, double r_i, double r_o, double *dRGB, double dOpacity, int iResolution, const double* tf_matrix) { const double dExtrusionVector[3] = {dAxisStop[0]-dAxisStart[0], dAxisStop[1]-dAxisStart[1], dAxisStop[2]-dAxisStart[2]}; double length = sqrt( dExtrusionVector[0]*dExtrusionVector[0] + dExtrusionVector[1]*dExtrusionVector[1] + dExtrusionVector[2]*dExtrusionVector[2] ) ; // create a disk in xy plane vtkDiskSource *diskSource = vtkDiskSource::New(); diskSource->SetInnerRadius( r_i ); diskSource->SetOuterRadius( r_o ); diskSource->SetCircumferentialResolution(iResolution); // extrude in +z vtkLinearExtrusionFilter *linearExtrusionFilter = vtkLinearExtrusionFilter::New(); #if VTK_MAJOR_VERSION>=6 linearExtrusionFilter->SetInputConnection( diskSource->GetOutputPort() ); #else linearExtrusionFilter->SetInput( diskSource->GetOutput() ); #endif linearExtrusionFilter->SetExtrusionTypeToNormalExtrusion(); linearExtrusionFilter->SetVector(0,0,length); // create transform to correctly orient and move the cylinder shell vtkTransform *transform = vtkTransform::New(); transform->PostMultiply(); double phi = atan2( dExtrusionVector[1], dExtrusionVector[0] ); double theta = acos( dExtrusionVector[2] / length ); transform->RotateY( theta / M_PI * 180 ); transform->RotateZ( phi / M_PI * 180 ); transform->Translate( dAxisStart ); if (tf_matrix) transform->Concatenate( tf_matrix ); vtkTransformPolyDataFilter *transformFilter = vtkTransformPolyDataFilter::New(); transformFilter->SetInputConnection( linearExtrusionFilter->GetOutputPort() ); transformFilter->SetTransform( transform ); vtkPolyDataMapper *mapper = vtkPolyDataMapper::New(); mapper->SetInputConnection( transformFilter->GetOutputPort() ); mapper->ScalarVisibilityOff(); vtkActor *actor = vtkLODActor::New(); actor->SetMapper( mapper ); m_PolyDataCollection->AddInputConnection( transformFilter->GetOutputPort()); actor->GetProperty()->SetColor(dRGB); actor->GetProperty()->SetOpacity(dOpacity); ActorColl->AddItem(actor); ren->AddActor(actor); } void VTKPrimitives::AddSphere(const double *dCenter, double fRadius, double *dRGB, double dOpacity, int iResolution, const double* tf_matrix) {//complete vtkSphereSource *Source = vtkSphereSource::New(); double center[3]={dCenter[0],dCenter[1],dCenter[2]}; Source->SetCenter(center); Source->SetRadius(fRadius); Source->SetPhiResolution(iResolution); Source->SetThetaResolution(iResolution); AddPolyData(Source->GetOutputPort(), dRGB, dOpacity, tf_matrix); Source->Delete(); } void VTKPrimitives::AddSphericalShell(const double *dCenter, double r_i, double r_o, double *dRGB, double dOpacity, int iResolution, const double* tf_matrix) {//complete #if (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION>=10) || (VTK_MAJOR_VERSION>=6) vtkSphereSource *Source_o = vtkSphereSource::New(); double center[3]={dCenter[0],dCenter[1],dCenter[2]}; Source_o->SetCenter(center); Source_o->SetRadius(r_o); Source_o->SetPhiResolution(iResolution); Source_o->SetThetaResolution(iResolution); vtkSphereSource *Source_i = vtkSphereSource::New(); Source_i->SetCenter(center); Source_i->SetRadius(r_i); Source_i->SetPhiResolution(iResolution); Source_i->SetThetaResolution(iResolution); vtkBooleanOperationPolyDataFilter* boolFilter = vtkBooleanOperationPolyDataFilter::New(); boolFilter->SetOperationToDifference(); boolFilter->SetInputConnection(0, Source_o->GetOutputPort()); boolFilter->SetInputConnection(1, Source_i->GetOutputPort()); //todo, we should remove the unnecessary scalar data produced by the filter... AddPolyData(boolFilter->GetOutputPort(), dRGB, dOpacity, tf_matrix); boolFilter->Delete(); Source_o->Delete(); Source_i->Delete(); #else cerr << "VTKPrimitives::AddSphericalShell: Error, spherical shell not supported by this vkt version, you require vtk 5.10 or higher." << endl; #endif } void VTKPrimitives::AddArrow(double *dStart, double *dEnd, double *dRGB, double dOpacity, int iResolution, const double* tf_matrix) { double alpha=0,beta=0; double dvector[3]={dEnd[0]-dStart[0],dEnd[1]-dStart[1],dEnd[2]-dStart[2]}; double length=sqrt( dvector[0]*dvector[0]+dvector[1]*dvector[1]+dvector[2]*dvector[2] ) ; if (length==0) { fprintf(stderr," Error Arrow Length ist Zero.. Abort..."); exit(1); } vtkArrowSource *Source = vtkArrowSource::New(); vtkTransform *transform = vtkTransform::New(); vtkTransformPolyDataFilter *transformFilter = vtkTransformPolyDataFilter::New(); Source->SetTipResolution(iResolution); Source->SetShaftResolution(iResolution); Source->SetTipLength(0.15); Source->SetTipRadius(0.03); Source->SetShaftRadius(0.01); alpha=VectorAngel(dvector[0],sqrt(dvector[1]*dvector[1]+dvector[2]*dvector[2]),0,0,1,0); beta=VectorAngel(0,dvector[1],dvector[2],0,1,0); if (dvector[0]>0) alpha=-alpha; if (dvector[2]<0) beta=-beta; transform->RotateWXYZ(beta,1,0,0); transform->RotateWXYZ(alpha,0,0,1); transform->RotateWXYZ(90,0,0,1); transform->PostMultiply(); #if VTK_MAJOR_VERSION>=6 transformFilter->SetInputConnection(Source->GetOutputPort()); #else transformFilter->SetInput(Source->GetOutput()); #endif transformFilter->SetTransform(transform); AddPolyData(transformFilter->GetOutputPort(), dRGB, dOpacity, tf_matrix); Source->Delete(); transform->Delete(); transformFilter->Delete(); } void VTKPrimitives::AddLabel(char *cText, double *dCoords, double *dRGB, double dOpacity, double dscale, const double* tf_matrix) { vtkVectorText *text = vtkVectorText::New(); vtkPolyDataMapper *Mapper = vtkPolyDataMapper::New(); vtkFollower *Actor = vtkFollower::New(); text->SetText(cText); vtkTransformPolyDataFilter* filter = vtkTransformPolyDataFilter::New(); vtkTransform* vtrans = vtkTransform::New(); #if VTK_MAJOR_VERSION>=6 filter->SetInputConnection(text->GetOutputPort()); #else filter->SetInput(text->GetOutput()); #endif if (tf_matrix) vtrans->SetMatrix(tf_matrix); filter->SetTransform(vtrans); m_PolyDataCollection->AddInputConnection(filter->GetOutputPort()); Mapper->SetInputConnection(filter->GetOutputPort()); Actor->SetMapper(Mapper); Actor->SetScale(dscale); Actor->SetCamera(ren->GetActiveCamera()); Actor->GetProperty()->SetColor(dRGB); Actor->GetProperty()->SetOpacity(dOpacity); Actor->SetPosition(dCoords); ren->AddActor(Actor); ActorColl->AddItem(Actor); Mapper->Delete(); text->Delete(); filter->Delete(); vtrans->Delete(); } void VTKPrimitives::AddRotationalPoly(const double *dCoords, unsigned int uiQtyCoords, const double *fRotAxis, double StartStopAngle[2], double *dRGB, double dOpacity, int iResolution, const double* tf_matrix) { unsigned int i=0; double start[3]={0,0,0},vector[3]={0,0,0}; vtkPoints *points = vtkPoints::New(); vtkCellArray *poly = vtkCellArray::New(); vtkPolyData *profile = vtkPolyData::New(); vtkRotationalExtrusionFilter *extrude = vtkRotationalExtrusionFilter::New(); vtkTransform *transform = vtkTransform::New(); vtkTransform *InvTransform = vtkTransform::New(); vtkTransformPolyDataFilter *transformFilter = vtkTransformPolyDataFilter::New(); vtkTransformPolyDataFilter *InvTransformFilter = vtkTransformPolyDataFilter::New(); vector[0]=fRotAxis[1]-fRotAxis[0]; vector[1]=fRotAxis[3]-fRotAxis[2]; vector[2]=fRotAxis[5]-fRotAxis[4]; double vec_len = sqrt(vector[0]*vector[0]+vector[1]*vector[1]+vector[2]*vector[2]); double vec_unit[3]={vector[0]/vec_len,vector[1]/vec_len,vector[2]/vec_len}; start[0]=fRotAxis[0]; start[1]=fRotAxis[2]; start[2]=fRotAxis[4]; double d = sqrt(vec_unit[1]*vec_unit[1]+vec_unit[2]*vec_unit[2]); double alpha = atan2(vec_unit[1],vec_unit[2])/acos(-1)*180; double beta = atan2(-vec_unit[0],d)/acos(-1)*180; for (i=0; iInsertPoint(i,dCoords[i],dCoords[uiQtyCoords+i],dCoords[2*uiQtyCoords+i]); poly->InsertNextCell(uiQtyCoords+1); for (i=0; iInsertCellPoint(i); poly->InsertCellPoint(0); profile->SetPoints(points); profile->SetPolys(poly); vtkTriangleFilter *tf = vtkTriangleFilter::New(); #if VTK_MAJOR_VERSION>=6 tf->SetInputData(profile); #else tf->SetInput(profile); #endif InvTransform->Translate(-start[0],-start[1],-start[2]); InvTransform->RotateX(alpha); InvTransform->RotateY(beta); InvTransformFilter->SetInputConnection(tf->GetOutputPort()); InvTransformFilter->SetTransform(InvTransform); extrude->SetInputConnection(InvTransformFilter->GetOutputPort()); extrude->SetResolution(iResolution); extrude->SetAngle(StartStopAngle[1]-StartStopAngle[0]); transform->RotateZ(-StartStopAngle[0]); transform->Translate(-start[0],-start[1],-start[2]); transform->RotateX(alpha); transform->RotateY(beta); transform->Inverse(); transform->PostMultiply(); transformFilter->SetInputConnection(extrude->GetOutputPort()); transformFilter->SetTransform(transform); AddPolyData(transformFilter->GetOutputPort(), dRGB, dOpacity, tf_matrix); points->Delete(); poly->Delete(); profile->Delete(); extrude->Delete(); transform->Delete(); transformFilter->Delete(); InvTransform->Delete(); InvTransformFilter->Delete(); } void VTKPrimitives::AddRotationalSolid(const double *dPoint, double fRadius, const double *fRotAxis, double *dRGB, double dOpacity, int iResolution, const double* tf_matrix) { vtkPoints *points = vtkPoints::New(); vtkCellArray *poly = vtkCellArray::New(); vtkPolyData *profile = vtkPolyData::New(); vtkRotationalExtrusionFilter *extrude = vtkRotationalExtrusionFilter::New(); vtkTransform *transform = vtkTransform::New(); vtkTransformPolyDataFilter *transformFilter = vtkTransformPolyDataFilter::New(); double vector[3]={0,0,0},start[3]={0,0,0},Footpoint[3]={0,0,0}; vector[0]=fRotAxis[1]-fRotAxis[0]; vector[1]=fRotAxis[3]-fRotAxis[2]; vector[2]=fRotAxis[5]-fRotAxis[4]; start[0]=fRotAxis[0]; start[1]=fRotAxis[2]; start[2]=fRotAxis[4]; double dSolidRadius=DistancePointLine(dPoint,start,vector,Footpoint); poly->InsertNextCell(iResolution+1); for (int i=0; iInsertPoint(i,dSolidRadius+fRadius*cos(i*2*PI/iResolution),0,fRadius*sin(i*2*PI/iResolution)); poly->InsertCellPoint(i); } poly->InsertCellPoint(0); profile->SetPoints(points); profile->SetLines(poly); #if VTK_MAJOR_VERSION>=6 extrude->SetInputData(profile); #else extrude->SetInput(profile); #endif extrude->SetResolution(iResolution); extrude->SetAngle(360.0); double alpha=VectorAngel(vector[0],sqrt(vector[1]*vector[1]+vector[2]*vector[2]),0,0,1,0); double beta=VectorAngel(0,vector[1],vector[2],0,1,0); if (vector[0]>0) alpha=-alpha; if (vector[2]<0) beta=-beta; transform->Translate(Footpoint); transform->RotateWXYZ(beta,1,0,0); transform->RotateWXYZ(alpha,0,0,1); transform->RotateWXYZ(-90,1,0,0); transform->PostMultiply(); transformFilter->SetInputConnection(extrude->GetOutputPort()); transformFilter->SetTransform(transform); AddPolyData(transformFilter->GetOutputPort(), dRGB, dOpacity, tf_matrix); points->Delete(); poly->Delete(); profile->Delete(); extrude->Delete(); transform->Delete(); transformFilter->Delete(); } void VTKPrimitives::AddSurface(double *dCoords, unsigned int uiQtyCoords, double *dRGB, double dOpacity, const double* tf_matrix) {//complete unsigned int i=0; vtkPoints *points = vtkPoints::New(); vtkCellArray *poly = vtkCellArray::New(); vtkPolyData *profile = vtkPolyData::New(); for (i=0; iInsertPoint(i,dCoords[3*i],dCoords[3*i+1],dCoords[3*i+2]); for (i=0; iInsertNextCell(3); poly->InsertCellPoint(i++); poly->InsertCellPoint(i++); poly->InsertCellPoint(i++); } profile->SetPoints(points); profile->SetPolys(poly); AddPolyData(profile, dRGB, dOpacity, tf_matrix); points->Delete(); poly->Delete(); profile->Delete(); } void VTKPrimitives::AddSTLObject(const char *Filename, double *dCenter, double *dRGB, double dOpacity, const double* tf_matrix) { //complete?? vtkSTLReader *part = vtkSTLReader::New(); part->SetFileName(Filename); vtkPolyDataMapper *partMapper = vtkPolyDataMapper::New(); vtkActor* actor = AddPolyData(part->GetOutputPort(), dRGB, dOpacity, tf_matrix); actor->SetPosition(dCenter); part->Delete(); partMapper->Delete(); } vtkActor* VTKPrimitives::AddPolyData(vtkPolyData* polydata, double *dRGB, double dOpacity, const double* tf_matrix) { vtkTransformPolyDataFilter* filter = vtkTransformPolyDataFilter::New(); vtkTransform* vtrans = vtkTransform::New(); #if VTK_MAJOR_VERSION>=6 filter->SetInputData(polydata); #else filter->SetInput(polydata); #endif if (tf_matrix) vtrans->SetMatrix(tf_matrix); filter->SetTransform(vtrans); #if VTK_MAJOR_VERSION>=6 m_PolyDataCollection->AddInputConnection(filter->GetOutputPort()); #else m_PolyDataCollection->AddInput(filter->GetOutput()); #endif vtkPolyDataMapper *Mapper = vtkPolyDataMapper::New(); Mapper->SetInputConnection(filter->GetOutputPort()); Mapper->ScalarVisibilityOff(); vtkLODActor *Actor = vtkLODActor::New(); Actor->SetMapper(Mapper); Actor->GetProperty()->RemoveAllTextures(); Actor->GetProperty()->SetColor(dRGB); Actor->GetProperty()->SetOpacity(dOpacity); ActorColl->AddItem(Actor); ren->AddActor(Actor); filter->Delete(); vtrans->Delete(); Mapper->Delete(); return Actor; } vtkActor* VTKPrimitives::AddPolyData(vtkAlgorithmOutput* polydata_port, double *dRGB, double dOpacity, const double* tf_matrix) { vtkTransformPolyDataFilter* filter = vtkTransformPolyDataFilter::New(); vtkTransform* vtrans = vtkTransform::New(); filter->SetInputConnection(polydata_port); if (tf_matrix) vtrans->SetMatrix(tf_matrix); filter->SetTransform(vtrans); #if VTK_MAJOR_VERSION>=6 m_PolyDataCollection->AddInputConnection(filter->GetOutputPort()); #else m_PolyDataCollection->AddInput(filter->GetOutput()); #endif vtkPolyDataMapper *Mapper = vtkPolyDataMapper::New(); Mapper->SetInputConnection(filter->GetOutputPort()); Mapper->ScalarVisibilityOff(); vtkLODActor *Actor = vtkLODActor::New(); Actor->SetMapper(Mapper); Actor->GetProperty()->RemoveAllTextures(); Actor->GetProperty()->SetColor(dRGB); Actor->GetProperty()->SetOpacity(dOpacity); ActorColl->AddItem(Actor); ren->AddActor(Actor); filter->Delete(); vtrans->Delete(); Mapper->Delete(); return Actor; } void VTKPrimitives::SetOpacity2All(double opacity) { ActorColl->InitTraversal(); vtkActor* act=NULL; while ((act=ActorColl->GetNextActor())) { act->GetProperty()->SetOpacity(opacity); } } void VTKPrimitives::WritePolyData2File(const char* filename, double scale) { cout << "VTKPrimitives::WritePolyData2File: Dump to vtk file: " << filename << " -- Using scale: " << scale << endl; vtkXMLPolyDataWriter* writer = vtkXMLPolyDataWriter::New(); writer->SetFileName(filename); if (scale==1.0) { #if VTK_MAJOR_VERSION>=6 writer->SetInputConnection(m_PolyDataCollection->GetOutputPort()); #else writer->SetInput(m_PolyDataCollection->GetOutput()); #endif writer->Write(); } else { vtkTransform *transform = vtkTransform::New(); vtkTransformPolyDataFilter *transformFilter = vtkTransformPolyDataFilter::New(); #if VTK_MAJOR_VERSION>=6 transformFilter->SetInputConnection(m_PolyDataCollection->GetOutputPort()); #else transformFilter->SetInput(m_PolyDataCollection->GetOutput()); #endif transform->Scale(scale,scale,scale); transformFilter->SetTransform(transform); #if VTK_MAJOR_VERSION>=6 writer->SetInputConnection(transformFilter->GetOutputPort()); #else writer->SetInput(transformFilter->GetOutput()); #endif writer->Write(); transform->Delete(); transformFilter->Delete(); } writer->Delete(); } void VTKPrimitives::WritePolyData2STL(const char* filename, double scale) { cout << "VTKPrimitives::WritePolyData2STL: Dump to stl file: " << filename << " -- Using scale: " << scale << endl; vtkTriangleFilter* filter = vtkTriangleFilter::New(); #if VTK_MAJOR_VERSION>=6 filter->SetInputConnection(m_PolyDataCollection->GetOutputPort()); #else filter->SetInput(m_PolyDataCollection->GetOutput()); #endif vtkSTLWriter* writer = vtkSTLWriter::New(); writer->SetFileName(filename); if (scale==1.0) { writer->SetInputConnection(filter->GetOutputPort()); writer->Write(); } else { vtkTransform *transform = vtkTransform::New(); vtkTransformPolyDataFilter *transformFilter = vtkTransformPolyDataFilter::New(); transformFilter->SetInputConnection(filter->GetOutputPort()); transform->Scale(scale,scale,scale); transformFilter->SetTransform(transform); #if VTK_MAJOR_VERSION>=6 writer->SetInputConnection(transformFilter->GetOutputPort()); #else writer->SetInput(transformFilter->GetOutput()); #endif writer->Write(); transform->Delete(); transformFilter->Delete(); } writer->Delete(); } void VTKPrimitives::WritePolyData2PLY(const char* filename, double scale) { cout << "VTKPrimitives::WritePolyData2PLY: Dump to ply file: " << filename << " -- Using scale: " << scale << endl; vtkTriangleFilter* filter = vtkTriangleFilter::New(); #if VTK_MAJOR_VERSION>=6 filter->SetInputConnection(m_PolyDataCollection->GetOutputPort()); #else filter->SetInput(m_PolyDataCollection->GetOutput()); #endif vtkPLYWriter* writer = vtkPLYWriter::New(); writer->SetFileName(filename); if (scale==1.0) { writer->SetInputConnection(filter->GetOutputPort()); writer->Write(); } else { vtkTransform *transform = vtkTransform::New(); vtkTransformPolyDataFilter *transformFilter = vtkTransformPolyDataFilter::New(); transformFilter->SetInputConnection(filter->GetOutputPort()); transform->Scale(scale,scale,scale); transformFilter->SetTransform(transform); #if VTK_MAJOR_VERSION>=6 writer->SetInputConnection(transformFilter->GetOutputPort()); #else writer->SetInput(transformFilter->GetOutput()); #endif writer->Write(); transform->Delete(); transformFilter->Delete(); } writer->Delete(); } double VTKPrimitives::VectorAngel(double dV1_1, double dV1_2, double dV1_3, double dV2_1, double dV2_2, double dV2_3) { double angel=0,dV1L,dV2L; double scalarP; dV1L=sqrt(dV1_1*dV1_1+dV1_2*dV1_2+dV1_3*dV1_3); dV2L=sqrt(dV2_1*dV2_1+dV2_2*dV2_2+dV2_3*dV2_3); scalarP=dV1_1*dV2_1+dV1_2*dV2_2+dV1_3*dV2_3; if ((dV1L*dV2L)==0) return 0; angel=scalarP/(dV1L*dV2L); if (angel>1) angel=0.0; else if (angel<-1) angel=180.0; else angel=acos(angel)*180/PI; return angel; } double VTKPrimitives::DistancePointLine(const double *dpoint, const double *dstart, const double *dvector, double *dFootpoint) { double dpos=0; dpos= ( (dpoint[0]-dstart[0])*dvector[0]+(dpoint[1]-dstart[1])*dvector[1]+(dpoint[2]-dstart[2])*dvector[2] ) /(dvector[0]*dvector[0]+dvector[1]*dvector[1]+dvector[2]*dvector[2]); for (int i=0; i<3; i++) dFootpoint[i]=dstart[i]+dpos*dvector[i]; return sqrt( (dpoint[0]-dFootpoint[0])*(dpoint[0]-dFootpoint[0]) + (dpoint[1]-dFootpoint[1])*(dpoint[1]-dFootpoint[1]) + (dpoint[2]-dFootpoint[2])*(dpoint[2]-dFootpoint[2]) ); } double VTKPrimitives::DistancePointPoint(const double *dpoint1, const double *dpoint2) { return sqrt( (dpoint1[0]-dpoint2[0])*(dpoint1[0]-dpoint2[0]) + (dpoint1[1]-dpoint2[1])*(dpoint1[1]-dpoint2[1]) + (dpoint1[2]-dpoint2[2])*(dpoint1[2]-dpoint2[2]) ); } double* VTKPrimitives::TransformCylindricalCoords(const double* in, double* out, unsigned int nrPoints) { unsigned int i,j,k; for (unsigned int n=0;n