Main Page | File List

vtkNURSubdivisionFilter.h

00001 /*================================*/
00002 /*================================*/
00003 // .NAME vtkNURSubdivisionFilter - Subdivision filter for non uniform catmull-clark subdivision
00004 // .SECTION Description
00005 // The vtkNURSubdivisionFilter provides a class for subdivision using a
00006 // non uniform catmull clarke scheme. It allows the definition of edge-weights
00007 // to additionally form the shape and to create sharp features and edges
00008 
00009 // .SECTION Further Work
00010 // This implementation only works on quad meshes as input. Furthermore the 
00011 // performance is very poor and there are still some calcutation mistakes
00012 // of sharp edges during the subdivision. These mistakes might occur because
00013 // of the deviding by zero problem which is not adressed in sufficeint detail
00014 // in the paper "Non Recursive Subdivision Surfaces" by Sederberg et al.
00015 // A reader routine for userdefined edge weights is also still needed.
00016  
00017 // .SECTION See Also
00018 // vtkApproximatingSubdivisionFilter 
00019 
00020 #ifndef _vtkNURSubdivisionFilter_h_
00021 #define _vtkNURSubdivisionFilter_h_
00022 
00023 #include "vtkApproximatingSubdivisionFilter.h"
00024 #include "vtkEdgeTable.h"
00025 #include "vtkLookupTable.h"
00026 
00027 class vtkPolyData;
00028 class vtkIntArray;
00029 class vtkPoints;
00030 class vtkIdList;
00031 
00032 class CWeightTable;
00033 
00034 class /*VTK_GRAPHICS_EXPORT*/ vtkNURSubdivisionFilter : public vtkApproximatingSubdivisionFilter
00035 {
00036  public:
00037   static vtkNURSubdivisionFilter *New();
00038   
00039   vtkTypeRevisionMacro(vtkNURSubdivisionFilter,vtkApproximatingSubdivisionFilter);
00040 
00041   void SetEdgeData(vtkEdgeTable *edges);
00042 
00043  protected:
00044   vtkNURSubdivisionFilter () {  nKnownEdgepoints=0;   // no edges known 
00045                 KnownEdgepoints=NULL; // edgetable empty
00046                 WeightTable = NULL;   // no wheigths known
00047                 };
00048 
00049   ~vtkNURSubdivisionFilter () {};
00054   void Execute();
00055   void GenerateSubdivisionPoints (vtkPolyData *inputDS, vtkIntArray *edgeData,
00056                                   vtkPoints *outputPts,
00057                                   vtkPointData *outputPD);
00061   void GenerateFacePoints();  
00062 
00066   void GenerateEdgePoints();  
00067   
00071   void GenerateVertexPoints();  
00072 
00076   float GetNewFEWeigth(vtkIdType FaceId, vtkIdType p1, vtkIdType p2); 
00077 
00081   float GetNewEEWeigth(vtkIdType EdgeIdForm, vtkIdType EdgeIdTo); 
00082 
00083 private:
00087   float dijk(vtkIdType pi, vtkIdType pj, short k);
00088 
00092   float alpha(vtkIdType pi, vtkIdType pj);
00093 
00094 
00098   vtkIdType LookupEdge(vtkIdType pi, vtkIdType pj); // lookup if we already know an edgepoint
00099 
00103   void EnterEdge(vtkIdType pi, vtkIdType pj, vtkIdType Id); // 
00104 
00108   vtkIdType *KnownEdgepoints; // 
00109 
00113   vtkIdType nKnownEdgepoints;   // 
00114 
00115   vtkNURSubdivisionFilter(const vtkNURSubdivisionFilter&); // Not implemented.
00116   void operator=(const vtkNURSubdivisionFilter&);          // Not implemented.
00117 
00118   CWeightTable  *WeightTable,   // Table that holds the weight information
00119           *TmpWeightTable;  // temporary table used to calculate new weights
00120 
00121   vtkCellArray  *InputFaces_;
00122   vtkPoints   *NewFacePoints_;  // holds all new calculated facepoints for all faces
00123   vtkPoints   *NewEdgePoints_;  // temporarily holds the new calculated edgepoints for one face
00124 
00125   vtkPolyData   *input_;      
00126   vtkPoints   *outputPts_;    // holds output points
00127   vtkCellArray  *outputPolys_;    // holds output polygons
00128 };
00129 
00130 
00131 // class to hold data for the edge weights
00132 class CWeightTable 
00133 {
00134 public:
00135 
00140   CWeightTable(vtkIdType NumberOfEdges) 
00141   {
00142     // allocate memory
00143     Data = (float *) malloc(sizeof(float)*NumberOfEdges);
00144     EdgeIds = (vtkIdType *) malloc(2*sizeof(vtkIdType)*NumberOfEdges);
00145     counter = 0;
00146   }   
00147 
00152   ~CWeightTable() {
00153     // free memory
00154     free(Data);
00155     free(EdgeIds);
00156   }
00157 
00162   float Lookup(vtkIdType pi, vtkIdType pj)
00163   {
00164     int i=0;
00165     vtkIdType *K = EdgeIds;
00166     // see if we already have this edge in our table
00167     while (i<counter) 
00168     {       
00169       if ( ((K[0] == pi) && (K[1] == pj)) ||
00170          ((K[1] == pi) && (K[0] == pj)) )
00171       {
00172         // if we know this edge we return the weigth.
00173         return Data[i];
00174       }
00175       K += 2;
00176       i++;
00177     }
00178     // if we do not know the edge we return 1 (uniform catmull-clark)
00179     return 1;
00180   }
00181 
00185   void Insert(vtkIdType pi, vtkIdType pj, float weight)
00186   {
00187     int i=0;
00188     vtkIdType *K = EdgeIds;
00189     
00190     while (i<counter) 
00191     {
00192       // see if we already know the edge weight 
00193       K += 2;
00194       if ( ((K[0] == pi) && (K[1] == pj)) ||
00195          ((K[1] == pi) && (K[0] == pj)) )
00196       {
00197         return;
00198       }
00199       i++;
00200     }
00201     // if not enter the new weight
00202     K[0] = pi;
00203     K[1] = pj;
00204     Data[counter]=weight;
00205     counter++;
00206   }
00207 
00211   void printself() {
00212     for (int i=0; i < counter; i++)
00213       printf("E[%i]-[%i, %i]: %f\n", i, EdgeIds[2*i], EdgeIds[2*i+1], Data[i]);
00214   }
00215 
00216 private:
00217   vtkIdType counter;  // counts how many weights we know
00218   float *Data;    // holds the edgeweights
00219   vtkIdType *EdgeIds; // holds the edges by saving two point ids
00220 };
00221 #endif

Generated on Thu Jun 26 02:28:45 2003 for vtkNURSubdivisionFilter by doxygen 1.3.2