/*========================================================================= medInria Copyright (c) INRIA 2013 - 2019. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ //dtk #include #include //medinria #include #include #include #include #include //vtk #include #include #include // ///////////////////////////////////////////////////////////////// // medRefineMeshProcessPrivate // ///////////////////////////////////////////////////////////////// class medRefineMeshProcessPrivate { public: dtkSmartPointer input; dtkSmartPointer output; double nbOfSubdivisions; bool changeMetaData; }; // ///////////////////////////////////////////////////////////////// // medRefineMeshProcess // ///////////////////////////////////////////////////////////////// medRefineMeshProcess::medRefineMeshProcess() : d(new medRefineMeshProcessPrivate) { d->input = nullptr; d->output = nullptr; d->nbOfSubdivisions = 1.0; d->changeMetaData = true; } medRefineMeshProcess::~medRefineMeshProcess() { delete d; d = nullptr; } bool medRefineMeshProcess::registered() { return dtkAbstractProcessFactory::instance()->registerProcessType("medRefineMeshProcess", createmedRefineMeshProcess); } QString medRefineMeshProcess::description() const { return "medRefineMeshProcess"; } void medRefineMeshProcess::setInput(medAbstractData *data, int channel) { d->input = data; } void medRefineMeshProcess::setParameter(double data, int channel) { d->nbOfSubdivisions = data; } void medRefineMeshProcess::setParameter(int data, int channel) { if(channel == 1) { d->changeMetaData = data; } } vtkMetaDataSet* medRefineMeshProcess::refineOneMetaDataSet(vtkMetaDataSet *inputMetaDaset) { vtkPolyData *polyData = dynamic_cast(inputMetaDaset->GetDataSet()); if(!polyData) { emit polyDataCastFailure(); return nullptr; } else { vtkSmartPointer triFilter = vtkSmartPointer::New(); triFilter->SetInputData(polyData); triFilter->Update(); vtkButterflySubdivisionFilter *loopRefineFilter = vtkButterflySubdivisionFilter::New(); loopRefineFilter->SetInputConnection(triFilter->GetOutputPort()); loopRefineFilter->SetNumberOfSubdivisions(d->nbOfSubdivisions); loopRefineFilter->SetGlobalWarningDisplay(true); loopRefineFilter->Update(); if (loopRefineFilter->GetOutput()->GetNumberOfCells() == 0) { qDebug() << metaObject()->className() << "::Subdivision failed check mesh quality."; return nullptr; } vtkMetaSurfaceMesh *smesh = vtkMetaSurfaceMesh::New(); smesh->SetDataSet(loopRefineFilter->GetOutput()); loopRefineFilter->Delete(); return smesh; } } int medRefineMeshProcess::update() { progressed(0); if (!d->input) { return medAbstractProcessLegacy::FAILURE; } if(!d->input->identifier().contains("vtkDataMesh")) { return medAbstractProcessLegacy::FAILURE; } d->output = medAbstractDataFactory::instance()->createSmartPointer(d->input->identifier()); if (d->input->identifier() == "vtkDataMesh4D") { vtkMetaDataSetSequence *inputSequence = static_cast(d->input->data()); vtkMetaDataSetSequence *outputSequence = vtkMetaDataSetSequence::New(); for(vtkMetaDataSet *inputMetaDataSet : inputSequence->GetMetaDataSetList()) { vtkMetaDataSet *outputMetaDataSet = refineOneMetaDataSet(inputMetaDataSet); outputMetaDataSet->SetTime(inputMetaDataSet->GetTime()); if (outputMetaDataSet == nullptr) { return medAbstractProcessLegacy::FAILURE; } outputSequence->AddMetaDataSet(outputMetaDataSet); outputMetaDataSet->Delete(); } d->output->setData(outputSequence); outputSequence->Delete(); } else { vtkMetaDataSet *inputMetaDataSet = static_cast(d->input->data()); vtkMetaDataSet *outputMetaDataSet = refineOneMetaDataSet(inputMetaDataSet); if (outputMetaDataSet == nullptr) { return medAbstractProcessLegacy::FAILURE; } d->output->setData(outputMetaDataSet); outputMetaDataSet->Delete(); } progressed(100); if (d->changeMetaData) { medUtilities::setDerivedMetaData(d->output, d->input, "refined"); } return medAbstractProcessLegacy::SUCCESS; } medAbstractData * medRefineMeshProcess::output() { return d->output; } // ///////////////////////////////////////////////////////////////// // Type instantiation // ///////////////////////////////////////////////////////////////// dtkAbstractProcess *createmedRefineMeshProcess() { return new medRefineMeshProcess; }