// // This example is a windows application (instead of a console application) // version of Examples/Tutorial/Step1/Cxx/Cone.cxx. It is organized in a more // object oriented manner and shows a fairly minimal windows VTK application. // // first include the required header files for the vtk classes we are using #include "vtkConeSource.h" #include "vtkPolyDataMapper.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include #include #include "vtkMath.h" #include "vtkIdList.h" #include "vtkObjectFactory.h" #include #include #include #include #include #include #include #include static HANDLE hinst; long FAR PASCAL WndProc(HWND, UINT, UINT, LONG); // define the vtk part as a simple c++ class class test { public: float m_test[100000]; }; class myVTKApp { public: myVTKApp(HWND parent); ~myVTKApp(); void make(vtkPolyData* m_base); void Execute(vtkPolyData* newPoly); void AppendData(vtkDataArray *dest, vtkDataArray *src, vtkIdType offset); vtkIdType *AppendCells(vtkIdType *pDest, vtkCellArray *src, vtkIdType offset); void AppendDifferentPoints(vtkDataArray *dest, vtkDataArray *src, vtkIdType offset); private: vtkPolyData* m_base; vtkAppendPolyData* m_append; test* atest; vtkRenderWindow *renWin; vtkRenderer *renderer; vtkRenderWindowInteractor *iren; vtkPolyDataNormals* m_normal; float tr[3]; }; int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) { static char szAppName[] = "Win32Cone"; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; if (!hPrevInstance) { wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.lpszMenuName = NULL; wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wndclass.lpszClassName = szAppName; RegisterClass (&wndclass); } hinst = hInstance; hwnd = CreateWindow ( szAppName, "Draw Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 480, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, nCmdShow); UpdateWindow (hwnd); double * aTest = new double [10000000]; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } delete[] aTest; return msg.wParam; } long FAR PASCAL WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam) { static HWND ewin; static myVTKApp *theVTKApp; switch (message) { case WM_CREATE: { ewin = CreateWindow("button","Exit", WS_CHILD | WS_VISIBLE | SS_CENTER, 0,400,400,60, hwnd,(HMENU)2, (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE), NULL); theVTKApp = new myVTKApp(hwnd); return 0; } case WM_COMMAND: switch (wParam) { case 2: PostQuitMessage (0); if (theVTKApp) { delete theVTKApp; theVTKApp = NULL; } break; } return 0; case WM_DESTROY: PostQuitMessage (0); if (theVTKApp) { delete theVTKApp; theVTKApp = NULL; } return 0; } return DefWindowProc (hwnd, message, wParam, lParam); } void myVTKApp::make(vtkPolyData* m_base){ // vtkConeSource *cone; vtkPoints* inPts = vtkPoints::New(); inPts->SetNumberOfPoints (4); inPts->SetPoint( 0, 2, 0.0, 0.0); inPts->SetPoint( 1, 10, 0.0, 0.0); inPts->SetPoint( 2, 10, 0.0, 20); inPts->SetPoint( 3, 0, 0.0,20); vtkCellArray* lines = vtkCellArray::New(); lines->InsertNextCell( 4); lines->InsertCellPoint( 0); lines->InsertCellPoint( 1); lines->InsertCellPoint( 2); lines->InsertCellPoint( 3); //lines->InsertCellPoint( 0); vtkPolyData* profile = vtkPolyData::New(); profile->SetPoints( inPts); profile->SetLines (lines); profile->Update(); vtkRotationalExtrusionFilter* extrude = vtkRotationalExtrusionFilter::New(); extrude->SetInput( profile); extrude->CappingOff (); extrude->SetResolution (40); extrude->SetAngle (360); extrude->Update(); /* vtkPointLocator *pointLocator = vtkPointLocator::New(); pointLocator->SetDataSet(extrude->GetOutput()); pointLocator->BuildLocator(); */ vtkPolyData* temp = extrude->GetOutput(); vtkTransform * tempT = vtkTransform::New(); tempT->Translate(tr[0],tr[1], tr[2]); vtkTransformPolyDataFilter* tempF = vtkTransformPolyDataFilter::New (); tempF->SetTransform(tempT); tempF->SetInput(temp); tempF->Update(); /*temp->DeepCopy(); temp->Update();*/ /* vtkIdList *cellIds = vtkIdList::New(); int numIds; pointLocator->FindClosestNPoints (2, 2, 0.0, 0.0,cellIds ) ; int a = cellIds->GetId(1); pointLocator->FindClosestNPoints (2, 10, 0.0, 0.0,cellIds ) ; int b = cellIds->GetId(1); pointLocator->FindClosestNPoints (2, 10, 0.0, 20,cellIds ) ; int c = cellIds->GetId(1); pointLocator->FindClosestNPoints (2, 0, 0.0,20,cellIds ) ; int d = cellIds->GetId(1); vtkCell* cell = temp->GetCell(0); temp->ReplaceCellPoint(0, b, temp->FindPoint (10, 0.0, 0.0)); temp->ReplaceCellPoint(1, b, temp->FindPoint (10, 0.0, 0.0)); temp->ReplaceCellPoint(1, c, temp->FindPoint (10, 0.0, 20)); temp->ReplaceCellPoint(2, c, temp->FindPoint (10, 0.0, 20)); temp->ReplaceCellPoint(2, d, temp->FindPoint ( 0, 0.0, 20)); temp->ReplaceCellPoint(3, d, temp->FindPoint ( 0, 0.0, 20)); */ // . // m_normal->SetInput(tempF->GetOutput()); // m_normal->Update(); /* m_append = vtkAppendPolyData::New(); m_append->AddInput(m_normal->GetOutput()); if (m_base != NULL){ m_append->AddInput(m_base); } // m_append->AddInput(m_base); // m_append->AddInput(m_normal->GetOutput()); m_append->Update(); */ Execute(tempF->GetOutput()); // vtkPolyData* polydata = vtkPolyData::New(); // m_base->DeepCopy(m_append->GetOutput()); // m_base->BuildLinks(); // m_base->Update(); // m_base->Reset(); // int cnt = m_append->GetOutput()->GetReferenceCount (); /* m_append->GetOutput()->SetReferenceCount (2); if (m_base != NULL){ m_base->Delete(); } m_base = m_append->GetOutput(); */ // m_append->RemoveInput(m_base); // m_append->RemoveInput(m_normal->GetOutput()); // m_append->Delete(); //m_base->Delete(); tempT->Delete(); tempF->Delete(); inPts->Delete(); lines->Delete(); profile->Delete(); extrude->Delete(); // pointLocator->Delete(); // temp->Delete(); // cellIds->Delete(); // m_normal->Delete(); } myVTKApp::myVTKApp(HWND hwnd) { vtkPolyDataMapper *coneMapper; vtkActor *coneActor; vtkInteractorStyleTrackball* track = vtkInteractorStyleTrackball::New(); // Similar to Examples/Tutorial/Step1/Cxx/Cone.cxx // We create the basic parts of a pipeline and connect them /// atest = new test; this->renderer = vtkRenderer::New(); this->renWin = vtkRenderWindow::New(); this->renWin->AddRenderer(this->renderer); // setup the parent window this->renWin->SetParentId(hwnd); this->iren = vtkRenderWindowInteractor::New(); this->iren->SetRenderWindow(this->renWin); this->iren->SetInteractorStyle(track); /* this->cone = vtkConeSource::New(); this->cone->SetHeight( 3.0 ); this->cone->SetRadius( 1.0 ); this->cone->SetResolution( 10 ); */ /* edge = vtkFeatureEdges::New(); edge->SetInput(cone->GetOutput()); edge->Update(); */ // this->coneActor->GetProperty()->SetRepresentationToWireframe (); m_base = vtkPolyData::New(); vtkPointSource * point = vtkPointSource::New(); point->SetCenter(-10,-10,-10); point->SetRadius(10); point->Update(); m_base->DeepCopy(point->GetOutput()); m_normal = vtkPolyDataNormals::New(); // m_base = NULL; for (int i = 0; i < 2; i++){ tr[0] = i * 00; tr[1] = i * 10; tr[2] = i * 0; make(m_base); } m_base->Squeeze(); // vtkMapper::SetResolveCoincidentTopologyToShiftZBuffer ( ) ; // vtkMapper::SetResolveCoincidentTopologyZShift ( 10 ) ; coneMapper = vtkPolyDataMapper::New(); coneMapper->SetInput(m_base); coneActor = vtkActor::New(); coneActor->SetMapper(coneMapper); renderer->AddActor(coneActor); renderer->SetBackground(0.2,0.4,0.3); renWin->SetSize(400,400); // m_append->Delete(); // Finally we start the interactor so that event will be handled renWin->Render(); this->iren->Initialize(); // delete atest; } myVTKApp::~myVTKApp() { renWin->Delete(); renderer->Delete(); iren->Delete(); // edge->Delete(); } void myVTKApp::Execute(vtkPolyData* newPoly) { int idx; vtkPolyData *ds; vtkPoints *inPts; vtkPoints *newPts; vtkCellArray *inVerts, *newVerts; vtkCellArray *inLines, *newLines; vtkCellArray *inPolys, *newPolys; vtkIdType sizePolys, numPolys; vtkCellArray *inStrips, *newStrips; vtkIdType numPts, numCells; vtkPointData *inPD = NULL; vtkCellData *inCD = NULL; vtkPolyData *output = m_base; vtkPointData *outputPD = output->GetPointData(); vtkCellData *outputCD = output->GetCellData(); vtkDataArray *newPtScalars = NULL; vtkDataArray *newPtVectors = NULL; vtkDataArray *newPtNormals = NULL; vtkDataArray *newPtTCoords = NULL; vtkDataArray *newPtTensors = NULL; int i; vtkIdType *pts, *pPolys, npts, ptId, cellId; // vtkDebugMacro(<<"Appending polydata"); // loop over all data sets, checking to see what point data is available. numPts = 0; numCells = 0; sizePolys = numPolys = 0; int countPD=0; int countCD=0; // These Field lists are very picky. Count the number of non empty inputs // so we can initialize them properly. ds = newPoly; if (ds != NULL) { if ( ds->GetNumberOfPoints() > 0) { ++countPD; } if (ds->GetNumberOfCells() > 0 ) { ++countCD; } // for a data set that has cells } // for a non NULL input // These are used to determine which fields are available for appending vtkDataSetAttributes::FieldList ptList(countPD); vtkDataSetAttributes::FieldList cellList(countCD); countPD = countCD = 0; ds = newPoly; if (ds != NULL) { // Skip points and cells if there are no points. Empty inputs may have no arrays. if ( ds->GetNumberOfPoints() > 0) { numPts += ds->GetNumberOfPoints(); // Take intersection of available point data fields. inPD = ds->GetPointData(); if ( countPD == 0 ) { ptList.InitializeFieldList(inPD); } else { ptList.IntersectFieldList(inPD); } ++countPD; } // for a data set that has points // Although we cannot have cells without points ... let's not nest. if (ds->GetNumberOfCells() > 0 ) { // keep track of the size of the poly cell array if (ds->GetPolys()) { numPolys += ds->GetPolys()->GetNumberOfCells(); sizePolys += ds->GetPolys()->GetNumberOfConnectivityEntries(); } numCells += ds->GetNumberOfCells(); inCD = ds->GetCellData(); if ( countCD == 0 ) { cellList.InitializeFieldList(inCD); } else { cellList.IntersectFieldList(inCD); } ++countCD; } // for a data set that has cells } // for a non NULL input if ( numPts < 1 || numCells < 1 ) { //vtkErrorMacro(<<"No data to append!"); return; } // Examine the points and check if they're the same type. If not, // use highest (double probably), otherwise the type of the first // array (float no doubt). Depends on defs in vtkSetGet.h - Warning. int ttype, firstType=1, AllSame=1; int pointtype = 0; // Keep track of types for fast point append ds = newPoly; if (ds != NULL && ds->GetNumberOfPoints()>0) { if ( firstType ) { firstType = 0; pointtype = ds->GetPoints()->GetData()->GetDataType(); } ttype = ds->GetPoints()->GetData()->GetDataType(); if ( ttype != pointtype ) { AllSame = 0; // vtkDebugMacro(<<"Different point data types"); } pointtype = pointtype > ttype ? pointtype : ttype; } // Allocate geometry/topology newPts = m_base->GetPoints(); newPts->GetData()->Resize (newPoly->GetPoints()->GetData()->GetNumberOfTuples() + m_base->GetPoints()->GetData()->GetNumberOfTuples() ); // newPts->Update(); newVerts = m_base->GetVerts(); // newVerts->Allocate(numCells*4); newLines = m_base->GetLines(); // newLines->Allocate(numCells*4); newStrips = m_base->GetStrips(); // newStrips->Allocate(numCells*4); newPolys = m_base->GetPolys(); pPolys = newPolys->WritePointer(numPolys, sizePolys); // These are created manually for faster execution // Uses the properties of the last input if ( ptList.IsAttributePresent(vtkDataSetAttributes::SCALARS) > -1 ) { outputPD->CopyScalarsOff(); newPtScalars = inPD->GetScalars()->MakeObject(); newPtScalars->SetName(inPD->GetScalars()->GetName()); newPtScalars->SetNumberOfTuples(numPts); } if ( ptList.IsAttributePresent(vtkDataSetAttributes::VECTORS) > -1 ) { outputPD->CopyVectorsOff(); newPtVectors = inPD->GetVectors()->MakeObject(); newPtVectors->SetName(inPD->GetVectors()->GetName()); newPtVectors->SetNumberOfTuples(numPts); } if ( ptList.IsAttributePresent(vtkDataSetAttributes::TENSORS) > -1 ) { outputPD->CopyTensorsOff(); newPtTensors = inPD->GetTensors()->MakeObject(); newPtTensors->SetName(inPD->GetTensors()->GetName()); newPtTensors->SetNumberOfTuples(numPts); } if ( ptList.IsAttributePresent(vtkDataSetAttributes::NORMALS) > -1 ) { outputPD->CopyNormalsOff(); newPtNormals = inPD->GetNormals()->MakeObject(); newPtNormals->SetName(inPD->GetNormals()->GetName()); newPtNormals->SetNumberOfTuples(numPts); } if ( ptList.IsAttributePresent(vtkDataSetAttributes::TCOORDS) > -1 ) { outputPD->CopyTCoordsOff(); newPtTCoords = inPD->GetTCoords()->MakeObject(); newPtTCoords->SetName(inPD->GetTCoords()->GetName()); newPtTCoords->SetNumberOfTuples(numPts); } // Allocate the point and cell data outputPD->CopyAllocate(ptList,numPts); outputCD->CopyAllocate(cellList,numCells); // loop over all input sets vtkIdType ptOffset = 0; vtkIdType cellOffset = 0; countPD = countCD = 0; // for (idx = 0; idx < this->NumberOfInputs; ++idx) // { // this->UpdateProgress(0.2 + 0.8*idx/this->NumberOfInputs); ds = newPoly; // this check is not necessary, but I'll put it in anyway if (ds != NULL) { numPts = ds->GetNumberOfPoints(); numCells = ds->GetNumberOfCells(); if ( numPts <= 0 && numCells <= 0 ) { // continue; //no input, just skip } inPD = ds->GetPointData(); inCD = ds->GetCellData(); inPts = ds->GetPoints(); inVerts = ds->GetVerts(); inLines = ds->GetLines(); inPolys = ds->GetPolys(); inStrips = ds->GetStrips(); if (ds->GetNumberOfPoints() > 0) { // copy points directly if (AllSame) { this->AppendData(newPts->GetData(), inPts->GetData(), ptOffset); } else { this->AppendDifferentPoints(newPts->GetData(), inPts->GetData(), ptOffset); } // copy scalars directly if (newPtScalars) { this->AppendData(newPtScalars,inPD->GetScalars(), ptOffset); } // copy normals directly if (newPtNormals) { this->AppendData(newPtNormals, inPD->GetNormals(), ptOffset); } // copy vectors directly if (newPtVectors) { this->AppendData(newPtVectors, inPD->GetVectors(), ptOffset); } // copy tcoords directly if (newPtTCoords) { this->AppendData(newPtTCoords, inPD->GetTCoords() , ptOffset); } // copy tensors directly if (newPtTensors) { this->AppendData(newPtTensors, inPD->GetTensors(), ptOffset); } // append the remainder of the field data for (ptId=0; ptId < numPts; ptId++) { outputPD->CopyData(ptList,inPD,countPD,ptId,ptId+ptOffset); } ++countPD; } if (ds->GetNumberOfCells() > 0) { // cell data could be made efficient like the point data, // but I will wait on that. // copy cell data for (cellId=0; cellId < numCells; cellId++) { outputCD->CopyData(cellList,inCD,countCD,cellId,cellId+cellOffset); } ++countCD; // copy the cells pPolys = this->AppendCells(pPolys, inPolys, ptOffset); // These other cell arrays could be made efficient like polys ... for (inVerts->InitTraversal(); inVerts->GetNextCell(npts,pts); ) { newVerts->InsertNextCell(npts); for (i=0; i < npts; i++) { newVerts->InsertCellPoint(pts[i]+ptOffset); } } for (inLines->InitTraversal(); inLines->GetNextCell(npts,pts); ) { newLines->InsertNextCell(npts); for (i=0; i < npts; i++) { newLines->InsertCellPoint(pts[i]+ptOffset); } } for (inStrips->InitTraversal(); inStrips->GetNextCell(npts,pts); ) { newStrips->InsertNextCell(npts); for (i=0; i < npts; i++) { newStrips->InsertCellPoint(pts[i]+ptOffset); } } } ptOffset += numPts; cellOffset += numCells; } // Update ourselves and release memory // // output->SetPoints(newPts); // newPts->Delete(); if (newPtScalars) { output->GetPointData()->SetScalars(newPtScalars); newPtScalars->Delete(); } if (newPtNormals) { output->GetPointData()->SetNormals(newPtNormals); newPtNormals->Delete(); } if (newPtVectors) { output->GetPointData()->SetVectors(newPtVectors); newPtVectors->Delete(); } if (newPtTCoords) { output->GetPointData()->SetTCoords(newPtTCoords); newPtTCoords->Delete(); } if (newPtTensors) { output->GetPointData()->SetTensors(newPtTensors); newPtTensors->Delete(); } /* if ( newVerts->GetNumberOfCells() > 0 ) { output->SetVerts(newVerts); } newVerts->Delete(); if ( newLines->GetNumberOfCells() > 0 ) { output->SetLines(newLines); } newLines->Delete(); if ( newPolys->GetNumberOfCells() > 0 ) { output->SetPolys(newPolys); } newPolys->Delete(); if ( newStrips->GetNumberOfCells() > 0 ) { output->SetStrips(newStrips); } newStrips->Delete(); */ // When all optimizations are complete, this squeeze will be unecessary. // (But it does not seem to cost much.) } void myVTKApp::AppendData(vtkDataArray *dest, vtkDataArray *src, vtkIdType offset) { void *pSrc, *pDest; vtkIdType length; // sanity checks if (src->GetDataType() != dest->GetDataType()) { // vtkErrorMacro("Data type mismatch."); return; } if (src->GetNumberOfComponents() != dest->GetNumberOfComponents()) { // vtkErrorMacro("NumberOfComponents mismatch."); return; } int a = src->GetNumberOfTuples(); int b = dest->GetNumberOfTuples(); if (src->GetNumberOfTuples() + offset > dest->GetNumberOfTuples()) { // vtkErrorMacro("Destination not big enough"); return; } // convert from tuples to components. offset *= src->GetNumberOfComponents(); length = src->GetMaxId() + 1; switch (src->GetDataType()) { case VTK_FLOAT: length *= sizeof(float); break; case VTK_DOUBLE: length *= sizeof(double); break; case VTK_INT: length *= sizeof(int); break; case VTK_UNSIGNED_INT: length *= sizeof(unsigned int); break; case VTK_LONG: length *= sizeof(long); break; case VTK_UNSIGNED_LONG: length *= sizeof(unsigned long); break; case VTK_SHORT: length *= sizeof(short); break; case VTK_UNSIGNED_SHORT: length *= sizeof(unsigned short); break; case VTK_UNSIGNED_CHAR: length *= sizeof(unsigned char); break; case VTK_CHAR: length *= sizeof(char); break; default: break; // vtkErrorMacro("Unknown data type " << src->GetDataType()); } pSrc = src->GetVoidPointer(0); pDest = dest->GetVoidPointer(offset); memcpy(pDest, pSrc, length); } void myVTKApp::AppendDifferentPoints(vtkDataArray *dest, vtkDataArray *src, vtkIdType offset) { float *fSrc; double *dSrc, *dDest; vtkIdType p; if (src->GetNumberOfTuples() + offset > dest->GetNumberOfTuples()) { // vtkErrorMacro("Destination not big enough"); return; } vtkIdType vals = src->GetMaxId()+1; switch (dest->GetDataType()) { // // Dest is FLOAT - if sources are not all same type, dest ought to // be double. (assuming float and double are the only choices) // case VTK_FLOAT: // vtkErrorMacro("Dest type should be double? " // << dest->GetDataType()); break; // // Dest is DOUBLE - sources may be mixed float/double combinations // case VTK_DOUBLE: dDest = (double*)(dest->GetVoidPointer(offset*src->GetNumberOfComponents())); // switch (src->GetDataType()) { case VTK_FLOAT: fSrc = (float*)(src->GetVoidPointer(0)); for (p=0; pGetVoidPointer(0)); memcpy(dDest, dSrc, vals*sizeof(double)); break; default: break; // vtkErrorMacro("Unknown data type " << dest->GetDataType()); } break; // default: break; // vtkErrorMacro("Unknown data type " << dest->GetDataType()); } } // returns the next pointer in dest vtkIdType *myVTKApp::AppendCells(vtkIdType *pDest, vtkCellArray *src, vtkIdType offset) { vtkIdType *pSrc, *end, *pNum; if (src == NULL) { return pDest; } pSrc = (vtkIdType*)(src->GetPointer()); end = pSrc + src->GetNumberOfConnectivityEntries(); pNum = pSrc; while (pSrc < end) { if (pSrc == pNum) { // move cell pointer to next cell pNum += 1+*pSrc; // copy the number of cells *pDest++ = *pSrc++; } else { // offset the point index *pDest++ = offset + *pSrc++; } } return pDest; }