码迷,mamicode.com
首页 > 其他好文 > 详细

[CC]平面拟合

时间:2016-11-25 17:01:22      阅读:307      评论:0      收藏:0      [点我收藏+]

标签:size   form   action   normal   containe   not   copy   convert   dir   

 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 way
105                 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 +Z
111                 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 precision
117                 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 DB
121                 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             else
130             {
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]平面拟合

标签:size   form   action   normal   containe   not   copy   convert   dir   

原文地址:http://www.cnblogs.com/yhlx125/p/6101759.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!