void ccPointPairRegistrationDlg::unstackRef() { unsigned pointCount = m_refPoints.size(); if (pointCount == 0) return; assert(refPointsTableWidget->rowCount() > 0); refPointsTableWidget->removeRow(refPointsTableWidget->rowCount()-1); //remove label assert(m_refPoints.getChildrenNumber() == pointCount); pointCount--; m_refPoints.removeChild(pointCount); //remove point m_refPoints.resize(pointCount); if (pointCount == 0) { //reset global shift (if any) m_refPoints.setGlobalShift(0,0,0); m_refPoints.setGlobalScale(1.0); } if (m_associatedWin) m_associatedWin->redraw(); onPointCountChanged(); }
void ccPointPairRegistrationDlg::unstackAligned() { unsigned pointCount = m_alignedPoints.size(); if (pointCount == 0) //nothing to do return; assert(alignedPointsTableWidget->rowCount() > 0); alignedPointsTableWidget->removeRow(alignedPointsTableWidget->rowCount()-1); //remove label assert(m_alignedPoints.getChildrenNumber() == pointCount); m_alignedPoints.removeChild(pointCount-1); //remove point m_alignedPoints.resize(pointCount-1); if (m_associatedWin) m_associatedWin->redraw(); onPointCountChanged(); }
void ccPointPairRegistrationDlg::removeRefPoint(int index, bool autoRemoveDualPoint/*=false*/) { if (index >= static_cast<int>(m_refPoints.size())) { ccLog::Error("[ccPointPairRegistrationDlg::removeRefPoint] Invalid index!"); assert(false); return; } int pointCount = static_cast<int>(m_refPoints.size()); //remove all labels above this index assert(m_refPoints.getChildrenNumber() == pointCount); { for (int i=pointCount-1; i>=index; --i) //downward for more efficiency { assert(m_refPoints.getChild(i) && m_refPoints.getChild(i)->isA(CC_TYPES::LABEL_2D)); m_refPoints.removeChild(i); } } //remove array row refPointsTableWidget->removeRow(index); //shift points & rename labels for (int i=index+1; i<pointCount; ++i) { *const_cast<CCVector3*>(m_refPoints.getPoint(i-1)) = *m_refPoints.getPoint(i); //new name QString pointName = QString("R%1").arg(i-1); //create new label cc2DLabel* label = CreateLabel(&m_refPoints,static_cast<unsigned>(i-1),pointName,m_associatedWin); m_refPoints.addChild(label); //update array refPointsTableWidget->setVerticalHeaderItem(i-1,new QTableWidgetItem(pointName)); } m_refPoints.invalidateBoundingBox(); pointCount--; assert(pointCount >= 0); m_refPoints.resize(static_cast<unsigned>(pointCount)); if (m_refPoints.size() == 0) { //reset global shift (if any) m_refPoints.setGlobalShift(0,0,0); m_refPoints.setGlobalScale(1.0); } if (m_associatedWin) { m_associatedWin->redraw(); } onPointCountChanged(); //auto-remove the other point? if ( autoRemoveDualPoint && index < static_cast<int>(m_alignedPoints.size()) && QMessageBox::question(0,"Remove dual point","Remove the equivalent aligned point as well?",QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes ) { removeAlignedPoint(index,false); } }
bool ccPointPairRegistrationDlg::addReferencePoint(CCVector3d& Pin, ccHObject* entity/*=0*/, bool shifted/*=true*/) { assert(entity == 0 || entity == m_reference.entity); ccGenericPointCloud* cloud = entity ? ccHObjectCaster::ToGenericPointCloud(entity) : 0; //first point? if (m_refPoints.size() == 0) { if (entity) //picked point { //simply copy the cloud global shift/scale if (cloud) { m_refPoints.setGlobalScale(cloud->getGlobalScale()); m_refPoints.setGlobalShift(cloud->getGlobalShift()); } } else //virtual point { m_refPoints.setGlobalScale(1.0); m_refPoints.setGlobalShift(0,0,0); if (!shifted) { //test that the input point has not too big coordinates bool shiftEnabled = false; CCVector3d Pshift(0,0,0); double scale = 1.0; //we use the aligned shift by default (if any) ccGenericPointCloud* alignedCloud = m_aligned.entity ? ccHObjectCaster::ToGenericPointCloud(m_aligned.entity) : 0; if (alignedCloud && alignedCloud->isShifted()) { Pshift = alignedCloud->getGlobalShift(); scale = alignedCloud->getGlobalScale(); shiftEnabled = true; } if (ccGlobalShiftManager::Handle(Pin,0,ccGlobalShiftManager::DIALOG_IF_NECESSARY,shiftEnabled,Pshift,&scale)) { m_refPoints.setGlobalShift(Pshift); m_refPoints.setGlobalScale(scale); } } } } PointCoordinateType sphereRadius = -PC_ONE; if (!convertToSphereCenter(Pin,entity,sphereRadius)) return false; //transform the input point in the 'global world' by default if (shifted && cloud) { Pin = cloud->toGlobal3d<double>(Pin); } //check that we don't duplicate points for (unsigned i=0; i<m_refPoints.size(); ++i) { //express the 'Pi' point in the current global coordinate system CCVector3d Pi = m_refPoints.toGlobal3d<PointCoordinateType>(*m_refPoints.getPoint(i)); if ((Pi-Pin).norm() < ZERO_TOLERANCE) { ccLog::Error("Point already picked or too close to an already selected one!"); return false; } } //add point to the 'reference' set unsigned newPointIndex = m_refPoints.size(); if (newPointIndex == m_refPoints.capacity() && !m_refPoints.reserve(newPointIndex+1)) { ccLog::Error("Not enough memory?!"); return false; } //shift point to the local coordinate system before pushing it CCVector3 P = m_refPoints.toLocal3pc<double>(Pin); m_refPoints.addPoint(P); QString pointName = QString("R%1").arg(newPointIndex); //add corresponding row in table addPointToTable(refPointsTableWidget,newPointIndex,Pin,pointName); //eventually add a label (or a sphere) if (sphereRadius <= 0) { cc2DLabel* label = CreateLabel(&m_refPoints,newPointIndex,pointName,m_associatedWin); m_refPoints.addChild(label); } else { ccGLMatrix trans; trans.setTranslation(Pin); ccSphere* sphere = new ccSphere(sphereRadius,&trans,pointName); sphere->showNameIn3D(true); sphere->setTempColor(ccColor::yellow,true); m_refPoints.addChild(sphere); } if (m_associatedWin) { m_associatedWin->redraw(); } onPointCountChanged(); return true; }
bool ccPointPairRegistrationDlg::addAlignedPoint(CCVector3d& Pin, ccHObject* entity/*=0*/, bool shifted/*=0*/) { //if the input point is not shifted, we shift it to the aligned coordinate system assert(entity == 0 || entity == m_aligned.entity); //first point? if (m_alignedPoints.size() == 0) { assert(m_aligned.entity); //simply copy the cloud global shift/scale ccGenericPointCloud* cloud = ccHObjectCaster::ToGenericPointCloud(m_aligned.entity); if (cloud) { m_alignedPoints.setGlobalScale(cloud->getGlobalScale()); m_alignedPoints.setGlobalShift(cloud->getGlobalShift()); } } PointCoordinateType sphereRadius = -PC_ONE; if (!convertToSphereCenter(Pin,entity,sphereRadius)) return false; //transform the input point in the 'global world' by default if (shifted) Pin = m_alignedPoints.toGlobal3d<double>(Pin); //check that we don't duplicate points for (unsigned i=0; i<m_alignedPoints.size(); ++i) { CCVector3d Pi = m_alignedPoints.toGlobal3d<PointCoordinateType>(*m_alignedPoints.getPoint(i)); if ((Pi-Pin).norm() < ZERO_TOLERANCE) { ccLog::Error("Point already picked or too close to an already selected one!"); return false; } } unsigned newPointIndex = m_alignedPoints.size(); if (newPointIndex == m_alignedPoints.capacity() && !m_alignedPoints.reserve(newPointIndex+1)) { ccLog::Error("Not enough memory?!"); return false; } //shift point to the local coordinate system before pushing it CCVector3 P = m_alignedPoints.toLocal3pc<double>(Pin); m_alignedPoints.addPoint(P); QString pointName = QString("A%1").arg(newPointIndex); //add corresponding row in table addPointToTable(alignedPointsTableWidget,newPointIndex,Pin,pointName); //eventually add a label (or a sphere) if (sphereRadius <= 0) { cc2DLabel* label = CreateLabel(&m_alignedPoints,newPointIndex,pointName,m_associatedWin); m_alignedPoints.addChild(label); } else { ccGLMatrix trans; trans.setTranslation(Pin); ccSphere* sphere = new ccSphere(sphereRadius,&trans,pointName); sphere->showNameIn3D(true); sphere->setTempColor(ccColor::red,true); m_alignedPoints.addChild(sphere); } if (m_associatedWin) m_associatedWin->redraw(); onPointCountChanged(); return true; }
bool ccPointPairRegistrationDlg::init( ccGLWindow* win, ccHObject* aligned, ccHObject* reference/*=0*/) { assert(win); assert(aligned); clear(); if (!aligned) { ccLog::Error("[PointPairRegistration] Need an aligned entity at least!"); return false; } //create dedicated 3D view if (!m_associatedWin) { //import GL filter so as to get the same rendering aspect! { ccGenericGLDisplay* sourceDisplay = aligned->getDisplay(); if (!sourceDisplay && reference) sourceDisplay = reference->getDisplay(); if (sourceDisplay) { ccGlFilter* filter = static_cast<ccGLWindow*>(sourceDisplay)->getGlFilter(); if (filter) win->setGlFilter(filter->clone()); } } linkWith(win); assert(m_associatedWin); } m_aligned = EntityContext(aligned); m_reference = EntityContext(reference); //add aligned entity to display ccViewportParameters originViewportParams; bool hasOriginViewportParams = false; if (aligned) { if (aligned->getDisplay()) { hasOriginViewportParams = true; originViewportParams = aligned->getDisplay()->getViewportParameters(); } //DGM: it's already in the global DB! //m_associatedWin->addToOwnDB(aligned); aligned->setDisplay(m_associatedWin); aligned->setVisible(true); aligned->setSelected(false); SetEnabled_recursive(aligned); //SetVisible_recursive(aligned); } //add reference entity (if any) to display if (reference) { if (!hasOriginViewportParams && reference->getDisplay()) { hasOriginViewportParams = true; originViewportParams = reference->getDisplay()->getViewportParameters(); } //DGM: it's already in the global DB! //m_associatedWin->addToOwnDB(reference); reference->setDisplay(m_associatedWin); reference->setVisible(true); reference->setSelected(false); SetEnabled_recursive(reference); //SetVisible_recursive(reference); } showReferenceCheckBox->setChecked(reference != 0); showReferenceCheckBox->setEnabled(reference != 0); showAlignedCheckBox->setChecked(true); m_associatedWin->showMaximized(); resetTitle(); if (hasOriginViewportParams) { m_associatedWin->setViewportParameters(originViewportParams); m_associatedWin->redraw(); } else { m_associatedWin->zoomGlobal(); m_associatedWin->redraw(); //already called by zoomGlobal } onPointCountChanged(); return true; }
void ccPointPairRegistrationDlg::removeRefPoint(int index, bool autoRemoveDualPoint/*=false*/) { if (index >= static_cast<int>(m_refPoints.size())) { ccLog::Error("[ccPointPairRegistrationDlg::removeRefPoint] Invalid index!"); assert(false); return; } int pointCount = static_cast<int>(m_refPoints.size()); //remove the label (or sphere) m_refPoints.removeChild(index); //remove array row refPointsTableWidget->removeRow(index); //shift points & rename labels for (int i = index + 1; i < pointCount; ++i) { *const_cast<CCVector3*>(m_refPoints.getPoint(i - 1)) = *m_refPoints.getPoint(i); //new name QString pointName = QString("R%1").arg(i - 1); //update the label (if any) ccHObject* child = m_refPoints.getChild(i - 1); if (child) { if (child->isKindOf(CC_TYPES::LABEL_2D)) { cc2DLabel* label = static_cast<cc2DLabel*>(child); label->clear(); CreateLabel(label, &m_refPoints, static_cast<unsigned>(i - 1), pointName, m_associatedWin); } else //probably a sphere { child->setName(pointName); } } //update array refPointsTableWidget->setVerticalHeaderItem(i - 1, new QTableWidgetItem(pointName)); } m_refPoints.invalidateBoundingBox(); pointCount--; assert(pointCount >= 0); m_refPoints.resize(static_cast<unsigned>(pointCount)); if (m_refPoints.size() == 0) { //reset global shift (if any) m_refPoints.setGlobalShift(0, 0, 0); m_refPoints.setGlobalScale(1.0); } if (m_associatedWin) { m_associatedWin->redraw(); } onPointCountChanged(); //auto-remove the other point? if ( autoRemoveDualPoint && index < static_cast<int>(m_alignedPoints.size()) && QMessageBox::question(0, "Remove dual point", "Remove the equivalent aligned point as well?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { removeAlignedPoint(index,false); } }