MeshEditor.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # include <algorithm>
00028 # include <QMenu>
00029 # include <QTimer>
00030 # include <Inventor/SoPickedPoint.h>
00031 # include <Inventor/details/SoFaceDetail.h>
00032 # include <Inventor/details/SoPointDetail.h>
00033 # include <Inventor/events/SoLocation2Event.h>
00034 # include <Inventor/events/SoMouseButtonEvent.h>
00035 # include <Inventor/nodes/SoBaseColor.h>
00036 # include <Inventor/nodes/SoCamera.h>
00037 # include <Inventor/nodes/SoCoordinate3.h>
00038 # include <Inventor/nodes/SoDirectionalLight.h>
00039 # include <Inventor/nodes/SoDrawStyle.h>
00040 # include <Inventor/nodes/SoFaceSet.h>
00041 # include <Inventor/nodes/SoLineSet.h>
00042 # include <Inventor/nodes/SoMarkerSet.h>
00043 # include <Inventor/nodes/SoSeparator.h>
00044 # include <Inventor/nodes/SoShapeHints.h>
00045 #endif
00046
00047 #include "MeshEditor.h"
00048 #include "SoFCMeshObject.h"
00049 #include <App/Document.h>
00050 #include <Mod/Mesh/App/MeshFeature.h>
00051 #include <Gui/Application.h>
00052 #include <Gui/View3DInventor.h>
00053 #include <Gui/View3DInventorViewer.h>
00054
00055 using namespace MeshGui;
00056
00057 PROPERTY_SOURCE(MeshGui::ViewProviderFace, Gui::ViewProviderDocumentObject)
00058
00059 ViewProviderFace::ViewProviderFace() : mesh(0), current_index(-1)
00060 {
00061 pcCoords = new SoCoordinate3();
00062 pcCoords->ref();
00063 pcCoords->point.setNum(0);
00064 pcFaces = new SoFaceSet;
00065 pcFaces->ref();
00066 pcMeshPick = new SoFCMeshPickNode();
00067 pcMeshPick->ref();
00068 }
00069
00070 ViewProviderFace::~ViewProviderFace()
00071 {
00072 pcCoords->unref();
00073 pcFaces->unref();
00074 pcMeshPick->unref();
00075 }
00076
00077 void ViewProviderFace::attach(App::DocumentObject* obj)
00078 {
00079 ViewProviderDocumentObject::attach(obj);
00080
00081 pcMeshPick->mesh.setValue(static_cast<Mesh::Feature*>(obj)->Mesh.getValuePtr());
00082
00083
00084 SoGroup* markers = new SoGroup();
00085 SoDrawStyle* pointStyle = new SoDrawStyle();
00086 pointStyle->style = SoDrawStyle::POINTS;
00087 pointStyle->pointSize = 8.0f;
00088 markers->addChild(pointStyle);
00089
00090 SoBaseColor * markcol = new SoBaseColor;
00091 markcol->rgb.setValue(1.0f, 1.0f, 0.0f);
00092 SoPointSet* marker = new SoPointSet();
00093 markers->addChild(markcol);
00094 markers->addChild(pcCoords);
00095 markers->addChild(marker);
00096
00097
00098 SoGroup* faces = new SoGroup();
00099 SoDrawStyle* faceStyle = new SoDrawStyle();
00100 faceStyle->style = SoDrawStyle::FILLED;
00101 faces->addChild(faceStyle);
00102
00103 SoShapeHints * flathints = new SoShapeHints;
00104
00105
00106 faces->addChild(flathints);
00107
00108 SoBaseColor* basecol = new SoBaseColor;
00109 if (mesh) {
00110 App::Color col = mesh->ShapeColor.getValue();
00111 basecol->rgb.setValue(col.r, col.g, col.b);
00112 }
00113 else {
00114 basecol->rgb.setValue(1.0f, 0.0f, 0.0f);
00115 }
00116
00117 faces->addChild(basecol);
00118 faces->addChild(pcCoords);
00119 faces->addChild(pcFaces);
00120
00121 SoGroup* face_marker = new SoGroup();
00122 face_marker->addChild(faces);
00123 face_marker->addChild(markers);
00124
00125 addDisplayMaskMode(markers, "Marker");
00126 addDisplayMaskMode(face_marker, "Face");
00127 setDisplayMode("Marker");
00128 }
00129
00130 void ViewProviderFace::setDisplayMode(const char* ModeName)
00131 {
00132 if (strcmp(ModeName, "Face") == 0)
00133 setDisplayMaskMode("Face");
00134 else if (strcmp(ModeName, "Marker") == 0)
00135 setDisplayMaskMode("Marker");
00136 ViewProviderDocumentObject::setDisplayMode(ModeName);
00137 }
00138
00139 const char* ViewProviderFace::getDefaultDisplayMode() const
00140 {
00141 return "Marker";
00142 }
00143
00144 std::vector<std::string> ViewProviderFace::getDisplayModes(void) const
00145 {
00146 std::vector<std::string> modes;
00147 modes.push_back("Marker");
00148 modes.push_back("Face");
00149 return modes;
00150 }
00151
00152 SoPickedPoint* ViewProviderFace::getPickedPoint(const SbVec2s& pos, const SoQtViewer* viewer) const
00153 {
00154 SoSeparator* root = new SoSeparator;
00155 root->ref();
00156 root->addChild(viewer->getHeadlight());
00157 root->addChild(viewer->getCamera());
00158 root->addChild(this->pcMeshPick);
00159
00160 SoRayPickAction rp(viewer->getViewportRegion());
00161 rp.setPoint(pos);
00162 rp.apply(root);
00163 root->unref();
00164
00165
00166 SoPickedPoint* pick = rp.getPickedPoint();
00167
00168 return (pick ? new SoPickedPoint(*pick) : 0);
00169 }
00170
00171
00172
00173
00174
00175 MeshFaceAddition::MeshFaceAddition(Gui::View3DInventor* parent)
00176 : QObject(parent), faceView(new MeshGui::ViewProviderFace())
00177 {
00178 }
00179
00180 MeshFaceAddition::~MeshFaceAddition()
00181 {
00182 delete faceView;
00183 }
00184
00185 void MeshFaceAddition::startEditing(MeshGui::ViewProviderMesh* vp)
00186 {
00187 Gui::View3DInventor* view = static_cast<Gui::View3DInventor*>(parent());
00188 Gui::View3DInventorViewer* viewer = view->getViewer();
00189 viewer->setEditing(true);
00190 viewer->setRedirectToSceneGraph(true);
00191
00192 faceView->mesh = vp;
00193 faceView->attach(vp->getObject());
00194 viewer->addViewProvider(faceView);
00195
00196 viewer->addEventCallback(SoEvent::getClassTypeId(),
00197 MeshFaceAddition::addFacetCallback, this);
00198 }
00199
00200 void MeshFaceAddition::finishEditing()
00201 {
00202 Gui::View3DInventor* view = static_cast<Gui::View3DInventor*>(parent());
00203 Gui::View3DInventorViewer* viewer = view->getViewer();
00204 viewer->setEditing(false);
00205 viewer->setRedirectToSceneGraph(false);
00206
00207 viewer->removeViewProvider(faceView);
00208
00209 viewer->removeEventCallback(SoEvent::getClassTypeId(),
00210 MeshFaceAddition::addFacetCallback, this);
00211 this->deleteLater();
00212 }
00213
00214 void MeshFaceAddition::addFace()
00215 {
00216 Mesh::Feature* mf = static_cast<Mesh::Feature*>(faceView->mesh->getObject());
00217 App::Document* doc = mf->getDocument();
00218 doc->openTransaction("Add triangle");
00219 Mesh::MeshObject* mesh = mf->Mesh.startEditing();
00220 MeshCore::MeshFacet f;
00221 f._aulPoints[0] = faceView->index[0];
00222 f._aulPoints[1] = faceView->index[1];
00223 f._aulPoints[2] = faceView->index[2];
00224 std::vector<MeshCore::MeshFacet> faces;
00225 faces.push_back(f);
00226 mesh->addFacets(faces);
00227 mf->Mesh.finishEditing();
00228 doc->commitTransaction();
00229
00230 clearPoints();
00231 }
00232
00233 void MeshFaceAddition::clearPoints()
00234 {
00235 faceView->index.clear();
00236 faceView->current_index = -1;
00237 faceView->pcCoords->point.setNum(0);
00238 faceView->setDisplayMode("Marker");
00239 }
00240
00241 void MeshFaceAddition::flipNormal()
00242 {
00243 if (faceView->index.size() < 3)
00244 return;
00245 std::swap(faceView->index[0], faceView->index[1]);
00246 SbVec3f v1 = faceView->pcCoords->point[0];
00247 SbVec3f v2 = faceView->pcCoords->point[1];
00248 faceView->pcCoords->point.set1Value(0, v2);
00249 faceView->pcCoords->point.set1Value(1, v1);
00250 }
00251
00252 bool MeshFaceAddition::addMarkerPoint()
00253 {
00254 if (faceView->current_index < 0)
00255 return false;
00256 if (faceView->index.size() >= 3)
00257 return false;
00258 faceView->index.push_back(faceView->current_index);
00259 faceView->current_index = -1;
00260 if (faceView->index.size() == 3)
00261 faceView->setDisplayMode("Face");
00262 return true;
00263 }
00264
00265 void MeshFaceAddition::showMarker(SoPickedPoint* pp)
00266 {
00267 const SbVec3f& vec = pp->getPoint();
00268 const SoDetail* detail = pp->getDetail();
00269 if (detail) {
00270 if (detail->isOfType(SoFaceDetail::getClassTypeId())) {
00271 const SoFaceDetail* fd = static_cast<const SoFaceDetail*>(detail);
00272 Mesh::Feature* mf = static_cast<Mesh::Feature*>(faceView->mesh->getObject());
00273 const MeshCore::MeshFacetArray& facets = mf->Mesh.getValuePtr()->getKernel().GetFacets();
00274 const MeshCore::MeshPointArray& points = mf->Mesh.getValuePtr()->getKernel().GetPoints();
00275
00276 int face_index = fd->getFaceIndex();
00277 if (face_index >= (int)facets.size())
00278 return;
00279
00280 MeshCore::MeshFacet f = facets[face_index];
00281 if (!f.HasOpenEdge())
00282 return;
00283
00284 int point_index = -1;
00285 float distance = FLT_MAX;
00286 Base::Vector3f pnt;
00287 SbVec3f face_pnt;
00288
00289 for (int i=0; i<3; i++) {
00290 int index = (int)f._aulPoints[i];
00291 if (std::find(faceView->index.begin(), faceView->index.end(), index) != faceView->index.end())
00292 continue;
00293 if (f._aulNeighbours[i] == ULONG_MAX ||
00294 f._aulNeighbours[(i+2)%3] == ULONG_MAX) {
00295 pnt = points[index];
00296 float len = Base::DistanceP2(pnt, Base::Vector3f(vec[0],vec[1],vec[2]));
00297 if (len < distance) {
00298 distance = len;
00299 point_index = index;
00300 face_pnt.setValue(pnt.x,pnt.y,pnt.z);
00301 }
00302 }
00303 }
00304
00305 if (point_index < 0)
00306 return;
00307
00308 int num = faceView->pcCoords->point.getNum();
00309 if (faceView->current_index >= 0) {
00310 num = std::max<int>(num-1, 0);
00311 }
00312 faceView->current_index = point_index;
00313 faceView->pcCoords->point.set1Value(num, face_pnt);
00314 return;
00315 }
00316 }
00317 }
00318
00319 void MeshFaceAddition::addFacetCallback(void * ud, SoEventCallback * n)
00320 {
00321 MeshFaceAddition* that = reinterpret_cast<MeshFaceAddition*>(ud);
00322 ViewProviderFace* face = that->faceView;
00323 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
00324
00325 const SoEvent* ev = n->getEvent();
00326 if (ev->getTypeId() == SoLocation2Event::getClassTypeId()) {
00327
00328 n->getAction()->setHandled();
00329 n->setHandled();
00330 if (face->index.size() < 3) {
00331 SoPickedPoint * point = face->getPickedPoint(ev->getPosition(), view);
00332 if (point) {
00333 that->showMarker(point);
00334 delete point;
00335 }
00336 }
00337 }
00338 else if (ev->getTypeId() == SoMouseButtonEvent::getClassTypeId()) {
00339
00340 n->getAction()->setHandled();
00341 n->setHandled();
00342 const SoMouseButtonEvent * mbe = static_cast<const SoMouseButtonEvent *>(ev);
00343 if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::DOWN) {
00344 that->addMarkerPoint();
00345 }
00346 else if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::UP) {
00347 if (face->index.size() == 3) {
00348 QMenu menu;
00349 QAction* add = menu.addAction(MeshFaceAddition::tr("Add triangle"));
00350 QAction* swp = menu.addAction(MeshFaceAddition::tr("Flip normal"));
00351 QAction* clr = menu.addAction(MeshFaceAddition::tr("Clear"));
00352 QAction* act = menu.exec(QCursor::pos());
00353 if (act == add) {
00354 QTimer::singleShot(300, that, SLOT(addFace()));
00355 }
00356 else if (act == swp) {
00357 QTimer::singleShot(300, that, SLOT(flipNormal()));
00358 }
00359 else if (act == clr) {
00360 QTimer::singleShot(300, that, SLOT(clearPoints()));
00361 }
00362 }
00363 }
00364 else if (mbe->getButton() == SoMouseButtonEvent::BUTTON2 && mbe->getState() == SoButtonEvent::UP) {
00365 QMenu menu;
00366 QAction* fin = menu.addAction(MeshFaceAddition::tr("Finish"));
00367 QAction* act = menu.exec(QCursor::pos());
00368 if (act == fin) {
00369 QTimer::singleShot(300, that, SLOT(finishEditing()));
00370 }
00371 }
00372 }
00373 }
00374
00375 #include "moc_MeshEditor.cpp"