You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
5.7 KiB
196 lines
5.7 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkTextureMapToCylinder.cxx,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkTextureMapToCylinder.h"
|
|
|
|
#include "vtkCellData.h"
|
|
#include "vtkDataSet.h"
|
|
#include "vtkFloatArray.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkLine.h"
|
|
#include "vtkMath.h"
|
|
#include "vtkOBBTree.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkPoints.h"
|
|
|
|
vtkCxxRevisionMacro(vtkTextureMapToCylinder, "$Revision: 1.32 $");
|
|
vtkStandardNewMacro(vtkTextureMapToCylinder);
|
|
|
|
// Create object with cylinder axis parallel to z-axis (points (0,0,-0.5)
|
|
// and (0,0,0.5)). The PreventSeam ivar is set to true. The cylinder is
|
|
// automatically generated.
|
|
vtkTextureMapToCylinder::vtkTextureMapToCylinder()
|
|
{
|
|
this->Point1[0] = 0.0;
|
|
this->Point1[1] = 0.0;
|
|
this->Point1[2] = -0.5;
|
|
|
|
this->Point2[0] = 0.0;
|
|
this->Point2[1] = 0.0;
|
|
this->Point2[2] = 0.5;
|
|
|
|
this->AutomaticCylinderGeneration = 1;
|
|
this->PreventSeam = 1;
|
|
}
|
|
|
|
int vtkTextureMapToCylinder::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()));
|
|
vtkDataSet *output = vtkDataSet::SafeDownCast(
|
|
outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
|
|
vtkFloatArray *newTCoords;
|
|
vtkIdType numPts=input->GetNumberOfPoints();
|
|
vtkIdType ptId;
|
|
int i;
|
|
double x[3], tc[2], thetaX, thetaY, closest[3], v[3];
|
|
double axis[3], vP[3], vec[3];
|
|
|
|
vtkDebugMacro(<<"Generating Cylindrical Texture Coordinates");
|
|
|
|
// First, copy the input to the output as a starting point
|
|
output->CopyStructure( input );
|
|
|
|
if ( numPts < 1 )
|
|
{
|
|
vtkErrorMacro(<<"Can't generate texture coordinates without points");
|
|
return 1;
|
|
}
|
|
|
|
if ( this->AutomaticCylinderGeneration )
|
|
{
|
|
vtkPoints *pts=vtkPoints::New(); pts->SetNumberOfPoints(numPts);
|
|
double corner[3], max[3], mid[3], min[3], size[3], l;
|
|
vtkOBBTree *OBB = vtkOBBTree::New();
|
|
|
|
for ( ptId=0; ptId < numPts; ptId++ )
|
|
{
|
|
input->GetPoint(ptId, x);
|
|
pts->SetPoint(ptId,x);
|
|
}
|
|
|
|
OBB->ComputeOBB(pts,corner,max,mid,min,size);
|
|
pts->Delete();
|
|
OBB->Delete();
|
|
|
|
for ( i=0; i < 3; i++)
|
|
{
|
|
l = (mid[i] + min[i])/2.0;
|
|
this->Point1[i] = corner[i] + l;
|
|
this->Point2[i] = corner[i] + max[i] + l;
|
|
}
|
|
|
|
vtkDebugMacro(<<"Cylinder axis computed as \tPoint1: ("
|
|
<< this->Point1[0] <<", " << this->Point1[1] <<", "
|
|
<< this->Point1[2] <<")\n\t\t\t\tPoint2: ("
|
|
<< this->Point2[0] <<", " << this->Point2[1] <<", "
|
|
<< this->Point2[2] <<")");
|
|
}
|
|
|
|
//compute axis which is theta (angle measure) origin
|
|
for ( i=0; i < 3; i++ )
|
|
{
|
|
axis[i] = this->Point2[i] - this->Point1[i];
|
|
}
|
|
if ( vtkMath::Norm(axis) == 0.0 )
|
|
{
|
|
vtkErrorMacro(<<"Bad cylinder axis");
|
|
return 1;
|
|
}
|
|
|
|
v[0] = 1.0; v[1] = v[2] = 0.0;
|
|
vtkMath::Cross(axis,v,vP);
|
|
if ( vtkMath::Norm(vP) == 0.0 )
|
|
{//must be prependicular
|
|
v[1] = 1.0; v[0] = v[2] = 0.0;
|
|
vtkMath::Cross(axis,v,vP);
|
|
}
|
|
vtkMath::Cross(vP,axis,vec);
|
|
if ( vtkMath::Normalize(vec) == 0.0 )
|
|
{
|
|
vtkErrorMacro(<<"Bad cylinder axis");
|
|
return 1;
|
|
}
|
|
newTCoords = vtkFloatArray::New();
|
|
newTCoords->SetNumberOfComponents(2);
|
|
newTCoords->Allocate(2*numPts);
|
|
|
|
//loop over all points computing spherical coordinates
|
|
for ( ptId=0; ptId < numPts; ptId++ )
|
|
{
|
|
input->GetPoint(ptId, x);
|
|
vtkLine::DistanceToLine(x,this->Point1,this->Point2,tc[1],closest);
|
|
|
|
for (i=0; i < 3; i++)
|
|
{
|
|
v[i] = x[i] - closest[i];
|
|
}
|
|
vtkMath::Normalize(v);
|
|
|
|
thetaX = acos ((double)vtkMath::Dot(v,vec));
|
|
vtkMath::Cross(vec,v,vP);
|
|
thetaY = vtkMath::Dot(axis,vP); //not really interested in angle, just +/- sign
|
|
|
|
if ( this->PreventSeam )
|
|
{
|
|
tc[0] = thetaX / vtkMath::Pi();
|
|
}
|
|
else
|
|
{
|
|
tc[0] = thetaX / (2.0*vtkMath::Pi());
|
|
if ( thetaY < 0.0 )
|
|
{
|
|
tc[0] = 1.0 - tc[0];
|
|
}
|
|
}
|
|
|
|
newTCoords->InsertTuple(ptId,tc);
|
|
}
|
|
|
|
output->GetPointData()->CopyTCoordsOff();
|
|
output->GetPointData()->PassData(input->GetPointData());
|
|
output->GetCellData()->PassData(input->GetCellData());
|
|
|
|
output->GetPointData()->SetTCoords(newTCoords);
|
|
newTCoords->Delete();
|
|
|
|
return 1;
|
|
}
|
|
|
|
void vtkTextureMapToCylinder::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "Automatic Cylinder Generation: " <<
|
|
(this->AutomaticCylinderGeneration ? "On\n" : "Off\n");
|
|
os << indent << "Prevent Seam: " <<
|
|
(this->PreventSeam ? "On\n" : "Off\n");
|
|
os << indent << "Point1: (" << this->Point1[0] << ", "
|
|
<< this->Point1[1] << ", "
|
|
<< this->Point1[2] << ")\n";
|
|
os << indent << "Point2: (" << this->Point2[0] << ", "
|
|
<< this->Point2[1] << ", "
|
|
<< this->Point2[2] << ")\n";
|
|
}
|
|
|