首页 > 代码库 > [CC]平面拟合

[CC]平面拟合

 MainWindow中的平面拟合方法,调用了ccPlane的Fit方法。

  1 void MainWindow::doActionFitPlane()  2 {  3     doComputePlaneOrientation(false);  4 }  5   6 void MainWindow::doActionFitFacet()  7 {  8     doComputePlaneOrientation(true);  9 } 10  11 static double s_polygonMaxEdgeLength = 0; 12 void MainWindow::doComputePlaneOrientation(bool fitFacet) 13 { 14     ccHObject::Container selectedEntities = m_selectedEntities; 15     size_t selNum = selectedEntities.size(); 16     if (selNum < 1) 17         return; 18  19     double maxEdgeLength = 0; 20     if (fitFacet) 21     { 22         bool ok = true; 23         maxEdgeLength = QInputDialog::getDouble(this,"Fit facet", "Max edge length (0 = no limit)", s_polygonMaxEdgeLength, 0, 1.0e9, 8, &ok); 24         if (!ok) 25             return; 26         s_polygonMaxEdgeLength = maxEdgeLength; 27     } 28  29     for (size_t i=0; i<selNum; ++i) 30     { 31         ccHObject* ent = selectedEntities[i]; 32         ccShiftedObject* shifted = 0; 33         CCLib::GenericIndexedCloudPersist* cloud = 0; 34  35         if (ent->isKindOf(CC_TYPES::POLY_LINE)) 36         { 37             ccPolyline* poly = ccHObjectCaster::ToPolyline(ent); 38             cloud = static_cast<CCLib::GenericIndexedCloudPersist*>(poly); 39             shifted = poly; 40         } 41         else 42         { 43             ccGenericPointCloud* gencloud = ccHObjectCaster::ToGenericPointCloud(ent); 44             if (gencloud) 45             { 46                 cloud = static_cast<CCLib::GenericIndexedCloudPersist*>(gencloud); 47                 shifted = gencloud; 48             } 49         } 50  51         if (cloud) 52         { 53             double rms = 0.0; 54             CCVector3 C,N; 55  56             ccHObject* plane = 0; 57             if (fitFacet) 58             { 59                 ccFacet* facet = ccFacet::Create(cloud, static_cast<PointCoordinateType>(maxEdgeLength)); 60                 if (facet) 61                 { 62                     plane = static_cast<ccHObject*>(facet); 63                     N = facet->getNormal(); 64                     C = facet->getCenter(); 65                     rms = facet->getRMS(); 66  67                     //manually copy shift & scale info! 68                     if (shifted) 69                     { 70                         ccPolyline* contour = facet->getContour(); 71                         if (contour) 72                         { 73                             contour->setGlobalScale(shifted->getGlobalScale()); 74                             contour->setGlobalShift(shifted->getGlobalShift()); 75                         } 76                     } 77                 } 78             } 79             else 80             { 81                 ccPlane* pPlane = ccPlane::Fit(cloud, &rms); 82                 if (pPlane) 83                 { 84                     plane = static_cast<ccHObject*>(pPlane); 85                     N = pPlane->getNormal(); 86                     C = *CCLib::Neighbourhood(cloud).getGravityCenter(); 87                     pPlane->enableStippling(true); 88                 } 89             } 90  91             //as all information appears in Console... 92             forceConsoleDisplay(); 93  94             if (plane) 95             { 96                 ccConsole::Print(QString("[Orientation] Entity ‘%1‘").arg(ent->getName())); 97                 ccConsole::Print("\t- plane fitting RMS: %f",rms); 98  99                 //We always consider the normal with a positive ‘Z‘ by default!100                 if (N.z < 0.0)101                     N *= -1.0;102                 ccConsole::Print("\t- normal: (%f,%f,%f)",N.x,N.y,N.z);103 104                 //we compute strike & dip by the way105                 PointCoordinateType dip = 0, dipDir = 0;106                 ccNormalVectors::ConvertNormalToDipAndDipDir(N,dip,dipDir);107                 QString dipAndDipDirStr = ccNormalVectors::ConvertDipAndDipDirToString(dip,dipDir);108                 ccConsole::Print(QString("\t- %1").arg(dipAndDipDirStr));109 110                 //hack: output the transformation matrix that would make this normal points towards +Z111                 ccGLMatrix makeZPosMatrix = ccGLMatrix::FromToRotation(N,CCVector3(0,0,PC_ONE));112                 CCVector3 Gt = C;113                 makeZPosMatrix.applyRotation(Gt);114                 makeZPosMatrix.setTranslation(C-Gt);115                 ccConsole::Print("[Orientation] A matrix that would make this plane horizontal (normal towards Z+) is:");116                 ccConsole::Print(makeZPosMatrix.toString(12, )); //full precision117                 ccConsole::Print("[Orientation] You can copy this matrix values (CTRL+C) and paste them in the ‘Apply transformation tool‘ dialog");118 119                 plane->setName(dipAndDipDirStr);120                 plane->applyGLTransformation_recursive(); //not yet in DB121                 plane->setVisible(true);122                 plane->setSelectionBehavior(ccHObject::SELECTION_FIT_BBOX);123 124                 ent->addChild(plane);125                 plane->setDisplay(ent->getDisplay());126                 plane->prepareDisplayForRefresh_recursive();127                 addToDB(plane);128             }129             else130             {131                 ccConsole::Warning(QString("Failed to fit a plane/facet on entity ‘%1‘").arg(ent->getName()));132             }133         }134     }135 136     refreshAll();137     updateUI();138 }

 

[CC]平面拟合