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 <QMenu>
00028 # include <Inventor/SbBox2s.h>
00029 # include <Inventor/SoPickedPoint.h>
00030 # include <Inventor/details/SoFaceDetail.h>
00031 # include <Inventor/events/SoMouseButtonEvent.h>
00032 # include <Inventor/nodes/SoBaseColor.h>
00033 # include <Inventor/nodes/SoCallback.h>
00034 # include <Inventor/nodes/SoCoordinate3.h>
00035 # include <Inventor/nodes/SoLightModel.h>
00036 # include <Inventor/nodes/SoIndexedFaceSet.h>
00037 # include <Inventor/nodes/SoIndexedLineSet.h>
00038 # include <Inventor/nodes/SoDrawStyle.h>
00039 # include <Inventor/nodes/SoMaterial.h>
00040 # include <Inventor/nodes/SoMaterialBinding.h>
00041 # include <Inventor/nodes/SoNormalBinding.h>
00042 # include <Inventor/nodes/SoOrthographicCamera.h>
00043 # include <Inventor/nodes/SoPerspectiveCamera.h>
00044 # include <Inventor/nodes/SoPolygonOffset.h>
00045 # include <Inventor/nodes/SoShapeHints.h>
00046 # include <Inventor/nodes/SoSeparator.h>
00047 #endif
00048
00050 #include <Base/Console.h>
00051 #include <Base/Exception.h>
00052 #include <Base/Sequencer.h>
00053 #include <Base/Tools.h>
00054 #include <Base/ViewProj.h>
00055
00056 #include <App/Document.h>
00057 #include <App/PropertyLinks.h>
00058
00059 #include <Gui/Application.h>
00060 #include <Gui/BitmapFactory.h>
00061 #include <Gui/Command.h>
00062 #include <Gui/Document.h>
00063 #include <Gui/SoFCOffscreenRenderer.h>
00064 #include <Gui/SoFCSelection.h>
00065 #include <Gui/SoFCSelectionAction.h>
00066 #include <Gui/MainWindow.h>
00067 #include <Gui/Selection.h>
00068 #include <Gui/Utilities.h>
00069 #include <Gui/Window.h>
00070 #include <Gui/WaitCursor.h>
00071 #include <Gui/View3DInventor.h>
00072 #include <Gui/View3DInventorViewer.h>
00073
00074 #include <Mod/Mesh/App/Core/Algorithm.h>
00075 #include <Mod/Mesh/App/Core/Evaluation.h>
00076 #include <Mod/Mesh/App/Core/Grid.h>
00077 #include <Mod/Mesh/App/Core/Iterator.h>
00078 #include <Mod/Mesh/App/Core/MeshIO.h>
00079 #include <Mod/Mesh/App/Core/Triangulation.h>
00080 #include <Mod/Mesh/App/Core/Visitor.h>
00081 #include <Mod/Mesh/App/Mesh.h>
00082 #include <Mod/Mesh/App/MeshFeature.h>
00083
00084 #include "ViewProvider.h"
00085 #include "SoFCIndexedFaceSet.h"
00086 #include "SoFCMeshObject.h"
00087
00088
00089 using namespace MeshGui;
00090
00091 using Mesh::Feature;
00092 using MeshCore::MeshKernel;
00093 using MeshCore::MeshPointIterator;
00094 using MeshCore::MeshFacetIterator;
00095 using MeshCore::MeshGeomFacet;
00096 using MeshCore::MeshFacet;
00097
00098 void ViewProviderMeshBuilder::buildNodes(const App::Property* prop, std::vector<SoNode*>& nodes) const
00099 {
00100 SoCoordinate3 *pcPointsCoord=0;
00101 SoIndexedFaceSet *pcFaces=0;
00102
00103 if (nodes.empty()) {
00104 pcPointsCoord = new SoCoordinate3();
00105 nodes.push_back(pcPointsCoord);
00106 pcFaces = new SoIndexedFaceSet();
00107 nodes.push_back(pcFaces);
00108 }
00109 else if (nodes.size() == 2) {
00110 if (nodes[0]->getTypeId() == SoCoordinate3::getClassTypeId())
00111 pcPointsCoord = static_cast<SoCoordinate3*>(nodes[0]);
00112 if (nodes[1]->getTypeId() == SoIndexedFaceSet::getClassTypeId())
00113 pcFaces = static_cast<SoIndexedFaceSet*>(nodes[1]);
00114 }
00115
00116 if (pcPointsCoord && pcFaces)
00117 createMesh(prop, pcPointsCoord, pcFaces);
00118 }
00119
00120 void ViewProviderMeshBuilder::createMesh(const App::Property* prop, SoCoordinate3* coords, SoIndexedFaceSet* faces) const
00121 {
00122 const Mesh::PropertyMeshKernel* mesh = static_cast<const Mesh::PropertyMeshKernel*>(prop);
00123 const MeshCore::MeshKernel& rcMesh = mesh->getValue().getKernel();
00124
00125
00126 const MeshCore::MeshPointArray& cP = rcMesh.GetPoints();
00127 coords->point.setNum(rcMesh.CountPoints());
00128 SbVec3f* verts = coords->point.startEditing();
00129 unsigned long i=0;
00130 for (MeshCore::MeshPointArray::_TConstIterator it = cP.begin(); it != cP.end(); ++it, i++) {
00131 verts[i].setValue(it->x, it->y, it->z);
00132 }
00133 coords->point.finishEditing();
00134
00135
00136 unsigned long j=0;
00137 const MeshCore::MeshFacetArray& cF = rcMesh.GetFacets();
00138 faces->coordIndex.setNum(4*rcMesh.CountFacets());
00139 int32_t* indices = faces->coordIndex.startEditing();
00140 for (MeshCore::MeshFacetArray::_TConstIterator it = cF.begin(); it != cF.end(); ++it, j++) {
00141 for (int i=0; i<3; i++) {
00142 indices[4*j+i] = it->_aulPoints[i];
00143 }
00144 indices[4*j+3] = SO_END_FACE_INDEX;
00145 }
00146 faces->coordIndex.finishEditing();
00147 }
00148
00149 PROPERTY_SOURCE(MeshGui::ViewProviderExport, Gui::ViewProviderDocumentObject)
00150
00151 ViewProviderExport::ViewProviderExport()
00152 {
00153 }
00154
00155 ViewProviderExport::~ViewProviderExport()
00156 {
00157 }
00158
00159 std::vector<std::string> ViewProviderExport::getDisplayModes(void) const
00160 {
00161 std::vector<std::string> mode;
00162 mode.push_back("");
00163 return mode;
00164 }
00165
00166 const char* ViewProviderExport::getDefaultDisplayMode() const
00167 {
00168 return "";
00169 }
00170
00171 QIcon ViewProviderExport::getIcon() const
00172 {
00173 const char * Mesh_Feature_xpm[] = {
00174 "22 22 6 1",
00175 ". c None",
00176 "# c #000000",
00177 "c c #ffff00",
00178 "a c #808080",
00179 "b c #c0c0c0",
00180 "f c #008000",
00181 ".............##.......",
00182 ".............###......",
00183 ".............#f##.....",
00184 ".#....####...#ff##....",
00185 ".##.##....#..#fff##...",
00186 ".###.........#ffff##..",
00187 ".####........#fffff##.",
00188 ".#####.......#ffffff##",
00189 ".............#########",
00190 ".####.................",
00191 "#abab##########.......",
00192 "#babababababab#.......",
00193 "#ababababababa#.......",
00194 "#babab################",
00195 "#abab##cccccccccccc##.",
00196 "#bab##cccccccccccc##..",
00197 "#ab##cccccccccccc##...",
00198 "#b##cccccccccccc##....",
00199 "###cccccccccccc##.....",
00200 "##cccccccccccc##......",
00201 "###############.......",
00202 "......................"};
00203 QPixmap px(Mesh_Feature_xpm);
00204 return px;
00205 }
00206
00207
00208
00209 App::PropertyFloatConstraint::Constraints ViewProviderMesh::floatRange = {1.0f,64.0f,1.0f};
00210 App::PropertyFloatConstraint::Constraints ViewProviderMesh::angleRange = {0.0f,180.0f,1.0f};
00211 App::PropertyIntegerConstraint::Constraints ViewProviderMesh::intPercent = {0,100,1};
00212 const char* ViewProviderMesh::LightingEnums[]= {"One side","Two side",NULL};
00213
00214 PROPERTY_SOURCE(MeshGui::ViewProviderMesh, Gui::ViewProviderGeometryObject)
00215
00216 ViewProviderMesh::ViewProviderMesh() : pcOpenEdge(0)
00217 {
00218 ADD_PROPERTY(LineTransparency,(0));
00219 LineTransparency.setConstraints(&intPercent);
00220 ADD_PROPERTY(LineWidth,(1.0f));
00221 LineWidth.setConstraints(&floatRange);
00222 ADD_PROPERTY(PointSize,(2.0f));
00223 PointSize.setConstraints(&floatRange);
00224 ADD_PROPERTY(CreaseAngle,(0.0f));
00225 CreaseAngle.setConstraints(&angleRange);
00226 ADD_PROPERTY(OpenEdges,(false));
00227 ADD_PROPERTY(Lighting,(1));
00228 Lighting.setEnums(LightingEnums);
00229 ADD_PROPERTY(LineColor,(0,0,0));
00230
00231 pOpenColor = new SoBaseColor();
00232 setOpenEdgeColorFrom(ShapeColor.getValue());
00233 pOpenColor->ref();
00234
00235 pcLineStyle = new SoDrawStyle();
00236 pcLineStyle->ref();
00237 pcLineStyle->style = SoDrawStyle::LINES;
00238 pcLineStyle->lineWidth = LineWidth.getValue();
00239
00240 pcPointStyle = new SoDrawStyle();
00241 pcPointStyle->ref();
00242 pcPointStyle->style = SoDrawStyle::POINTS;
00243 pcPointStyle->pointSize = PointSize.getValue();
00244
00245 pShapeHints = new SoShapeHints;
00246 pShapeHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE;
00247 pShapeHints->ref();
00248
00249 pcMatBinding = new SoMaterialBinding;
00250 pcMatBinding->value = SoMaterialBinding::OVERALL;
00251 pcMatBinding->ref();
00252
00253 pLineColor = new SoMaterial;
00254 pLineColor->ref();
00255 LineColor.touch();
00256
00257
00258 Base::Reference<ParameterGrp> hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("Mod/Mesh");
00259
00260
00261 App::Color color = ShapeColor.getValue();
00262 unsigned long current = color.getPackedValue();
00263 unsigned long setting = hGrp->GetUnsigned("MeshColor", current);
00264 if (current != setting) {
00265 color.setPackedValue((uint32_t)setting);
00266 ShapeColor.setValue(color);
00267 }
00268 Transparency.setValue(hGrp->GetInt("MeshTransparency", 0));
00269
00270
00271 color = LineColor.getValue();
00272 current = color.getPackedValue();
00273 setting = hGrp->GetUnsigned("LineColor", current);
00274 if (current != setting) {
00275 color.setPackedValue((uint32_t)setting);
00276 LineColor.setValue(color);
00277 }
00278 LineTransparency.setValue(hGrp->GetInt("LineTransparency", 0));
00279
00280 bool twoside = hGrp->GetBool("TwoSideRendering", false);
00281 if (twoside) Lighting.setValue(1);
00282 else Lighting.setValue((long)0);
00283
00284 bool normal_per_vertex = hGrp->GetBool("VertexPerNormals", false);
00285 if (normal_per_vertex) {
00286 double angle = hGrp->GetFloat("CreaseAngle", 0.0);
00287 CreaseAngle.setValue(angle);
00288 }
00289
00290 if (hGrp->GetBool("ShowBoundingBox", false))
00291 pcHighlight->style = Gui::SoFCSelection::BOX;
00292 }
00293
00294 ViewProviderMesh::~ViewProviderMesh()
00295 {
00296 pOpenColor->unref();
00297 pcLineStyle->unref();
00298 pcPointStyle->unref();
00299 pShapeHints->unref();
00300 pcMatBinding->unref();
00301 pLineColor->unref();
00302 }
00303
00304 void ViewProviderMesh::onChanged(const App::Property* prop)
00305 {
00306
00307 if (prop == &ShapeColor || prop == &ShapeMaterial) {
00308 pcMatBinding->value = SoMaterialBinding::OVERALL;
00309 }
00310 if (prop == &LineTransparency) {
00311 float trans = LineTransparency.getValue()/100.0f;
00312 pLineColor->transparency = trans;
00313 }
00314 else if (prop == &LineWidth) {
00315 pcLineStyle->lineWidth = LineWidth.getValue();
00316 }
00317 else if (prop == &PointSize) {
00318 pcPointStyle->pointSize = PointSize.getValue();
00319 }
00320 else if (prop == &CreaseAngle) {
00321 pShapeHints->creaseAngle = (F_PI*CreaseAngle.getValue())/180.0;
00322 }
00323 else if (prop == &OpenEdges) {
00324 showOpenEdges(OpenEdges.getValue());
00325 }
00326 else if (prop == &Lighting) {
00327 if (Lighting.getValue() == 0) {
00328 pShapeHints->vertexOrdering = SoShapeHints::UNKNOWN_ORDERING;
00329
00330 }
00331 else {
00332 pShapeHints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
00333 }
00334 }
00335 else if (prop == &LineColor) {
00336 const App::Color& c = LineColor.getValue();
00337 pLineColor->diffuseColor.setValue(c.r,c.g,c.b);
00338 }
00339 else {
00340
00341 if (prop == &ShapeColor) {
00342 setOpenEdgeColorFrom(ShapeColor.getValue());
00343 }
00344 else if (prop == &ShapeMaterial) {
00345 setOpenEdgeColorFrom(ShapeMaterial.getValue().diffuseColor);
00346 }
00347 }
00348
00349 ViewProviderGeometryObject::onChanged(prop);
00350 }
00351
00352 void ViewProviderMesh::setOpenEdgeColorFrom(const App::Color& c)
00353 {
00354 float r=1.0f-c.r; r = r < 0.5f ? 0.0f : 1.0f;
00355 float g=1.0f-c.g; g = g < 0.5f ? 0.0f : 1.0f;
00356 float b=1.0f-c.b; b = b < 0.5f ? 0.0f : 1.0f;
00357 pOpenColor->rgb.setValue(r, g, b);
00358 }
00359
00360 SoShape* ViewProviderMesh::getShapeNode() const
00361 {
00362 return 0;
00363 }
00364
00365 SoNode* ViewProviderMesh::getCoordNode() const
00366 {
00367 return 0;
00368 }
00369
00374 void ViewProviderMesh::attach(App::DocumentObject *pcFeat)
00375 {
00376 ViewProviderGeometryObject::attach(pcFeat);
00377
00378
00379
00380
00381
00382
00383
00384
00385 SoGroup* pcFlatRoot = new SoGroup();
00386 pcFlatRoot->addChild(pShapeHints);
00387 pcFlatRoot->addChild(pcShapeMaterial);
00388 pcFlatRoot->addChild(pcMatBinding);
00389 pcFlatRoot->addChild(pcHighlight);
00390 addDisplayMaskMode(pcFlatRoot, "Flat");
00391
00392
00393 SoGroup* pcPointRoot = new SoGroup();
00394 pcPointRoot->addChild(pcPointStyle);
00395 pcPointRoot->addChild(pcFlatRoot);
00396 addDisplayMaskMode(pcPointRoot, "Point");
00397
00398
00399 SoLightModel* pcLightModel = new SoLightModel();
00400 pcLightModel->model = SoLightModel::BASE_COLOR;
00401 SoGroup* pcWireRoot = new SoGroup();
00402 pcWireRoot->addChild(pcLineStyle);
00403 pcWireRoot->addChild(pcLightModel);
00404 SoMaterialBinding* binding = new SoMaterialBinding;
00405 binding->value = SoMaterialBinding::OVERALL;
00406 pcWireRoot->addChild(binding);
00407 pcWireRoot->addChild(pLineColor);
00408 pcWireRoot->addChild(pcHighlight);
00409 addDisplayMaskMode(pcWireRoot, "Wireframe");
00410
00411
00412
00413
00414 SoPolygonOffset* offset = new SoPolygonOffset();
00415 offset->styles = SoPolygonOffset::LINES;
00416 offset->factor = -2.0f;
00417 offset->units = 1.0f;
00418 SoGroup* pcFlatWireRoot = new SoGroup();
00419 pcFlatWireRoot->addChild(pcFlatRoot);
00420 pcFlatWireRoot->addChild(offset);
00421 pcFlatWireRoot->addChild(pcWireRoot);
00422 addDisplayMaskMode(pcFlatWireRoot, "FlatWireframe");
00423 }
00424
00425 QIcon ViewProviderMesh::getIcon() const
00426 {
00427 #if 1
00428 static QIcon icon = Gui::BitmapFactory().pixmap("Tree_Mesh");
00429 return icon;
00430 #else
00431 static const char * const Mesh_Feature_xpm[] = {
00432 "16 16 4 1",
00433 ". c None",
00434 "# c #000000",
00435 "s c #BEC2FC",
00436 "g c #00FF00",
00437 ".......##.......",
00438 "....#######.....",
00439 "..##ggg#ggg#....",
00440 "##ggggg#gggg##..",
00441 "#g#ggg#gggggg##.",
00442 "#gg#gg#gggg###s.",
00443 "#gg#gg#gg##gg#s.",
00444 "#ggg#####ggg#ss.",
00445 "#gggg##gggg#ss..",
00446 ".#g##g#gggg#s...",
00447 ".##ggg#ggg#ss...",
00448 ".##gggg#g#ss....",
00449 "..s#####g#s.....",
00450 "....sss##ss.....",
00451 "........ss......",
00452 "................"};
00453 QPixmap px(Mesh_Feature_xpm);
00454 return px;
00455 #endif
00456 }
00457
00458 void ViewProviderMesh::setDisplayMode(const char* ModeName)
00459 {
00460 if (strcmp("Shaded",ModeName)==0)
00461 setDisplayMaskMode("Flat");
00462 else if (strcmp("Points",ModeName)==0)
00463 setDisplayMaskMode("Point");
00464 else if (strcmp("Flat Lines",ModeName)==0)
00465 setDisplayMaskMode("FlatWireframe");
00466 else if (strcmp("Wireframe",ModeName)==0)
00467 setDisplayMaskMode("Wireframe");
00468
00469 ViewProviderGeometryObject::setDisplayMode(ModeName);
00470 }
00471
00472 std::vector<std::string> ViewProviderMesh::getDisplayModes(void) const
00473 {
00474 std::vector<std::string> StrList;
00475
00476
00477 StrList.push_back("Shaded");
00478 StrList.push_back("Wireframe");
00479 StrList.push_back("Flat Lines");
00480 StrList.push_back("Points");
00481
00482 return StrList;
00483 }
00484
00485 bool ViewProviderMesh::setEdit(int ModNum)
00486 {
00487 if (ModNum == ViewProvider::Transform)
00488 return ViewProviderGeometryObject::setEdit(ModNum);
00489 return true;
00490 }
00491
00492 void ViewProviderMesh::unsetEdit(int ModNum)
00493 {
00494 if (ModNum == ViewProvider::Transform)
00495 ViewProviderGeometryObject::unsetEdit(ModNum);
00496 }
00497
00498 bool ViewProviderMesh::createToolMesh(const std::vector<SbVec2f>& rclPoly, const SbViewVolume& vol,
00499 const Base::Vector3f& rcNormal, std::vector<MeshCore::MeshGeomFacet>& aFaces)
00500 {
00501 float fX, fY, fZ;
00502 SbVec3f pt1, pt2, pt3, pt4;
00503 MeshGeomFacet face;
00504 std::vector<Base::Vector3f> top, bottom, polygon;
00505
00506 for (std::vector<SbVec2f>::const_iterator it = rclPoly.begin(); it != rclPoly.end(); ++it) {
00507
00508 std::vector<SbVec2f>::const_iterator nt = it + 1;
00509 if (nt == rclPoly.end())
00510 nt = rclPoly.begin();
00511 else if (*it == *nt)
00512 continue;
00513
00514 vol.projectPointToLine(*it, pt1, pt2);
00515 vol.projectPointToLine(*nt, pt3, pt4);
00516
00517
00518 pt1.getValue(fX, fY, fZ);
00519 face._aclPoints[0].Set(fX, fY, fZ);
00520 pt4.getValue(fX, fY, fZ);
00521 face._aclPoints[1].Set(fX, fY, fZ);
00522 pt3.getValue(fX, fY, fZ);
00523 face._aclPoints[2].Set(fX, fY, fZ);
00524 if (face.Area() > 0)
00525 aFaces.push_back(face);
00526
00527
00528 pt1.getValue(fX, fY, fZ);
00529 face._aclPoints[0].Set(fX, fY, fZ);
00530 pt2.getValue(fX, fY, fZ);
00531 face._aclPoints[1].Set(fX, fY, fZ);
00532 pt4.getValue(fX, fY, fZ);
00533 face._aclPoints[2].Set(fX, fY, fZ);
00534 if (face.Area() > 0)
00535 aFaces.push_back(face);
00536
00537 if (it+1 < rclPoly.end()) {
00538 pt1.getValue(fX, fY, fZ);
00539 top.push_back( Base::Vector3f(fX, fY, fZ) );
00540 pt2.getValue(fX, fY, fZ);
00541 bottom.push_back( Base::Vector3f(fX, fY, fZ) );
00542
00543 it->getValue(fX, fY);
00544 polygon.push_back( Base::Vector3f(fX, fY, 0.0f) );
00545 }
00546 }
00547
00548
00549 std::vector<MeshGeomFacet> aLid;
00550 MeshCore::EarClippingTriangulator cTria;
00551 cTria.SetPolygon(polygon);
00552 bool ok = cTria.TriangulatePolygon();
00553
00554 std::vector<MeshFacet> faces = cTria.GetFacets();
00555 for (std::vector<MeshFacet>::iterator itF = faces.begin(); itF != faces.end(); ++itF) {
00556 MeshGeomFacet topFacet;
00557 topFacet._aclPoints[0] = top[itF->_aulPoints[0]];
00558 topFacet._aclPoints[1] = top[itF->_aulPoints[1]];
00559 topFacet._aclPoints[2] = top[itF->_aulPoints[2]];
00560 if (topFacet.GetNormal() * rcNormal < 0) {
00561 std::swap(topFacet._aclPoints[1], topFacet._aclPoints[2]);
00562 topFacet.CalcNormal();
00563 }
00564 aFaces.push_back(topFacet);
00565
00566 MeshGeomFacet botFacet;
00567 botFacet._aclPoints[0] = bottom[itF->_aulPoints[0]];
00568 botFacet._aclPoints[1] = bottom[itF->_aulPoints[1]];
00569 botFacet._aclPoints[2] = bottom[itF->_aulPoints[2]];
00570 if (botFacet.GetNormal() * rcNormal > 0) {
00571 std::swap(botFacet._aclPoints[1], botFacet._aclPoints[2]);
00572 botFacet.CalcNormal();
00573 }
00574 aFaces.push_back(botFacet);
00575 }
00576
00577 return ok;
00578 }
00579
00580 void ViewProviderMesh::showOpenEdges(bool show)
00581 {
00582 }
00583
00584 void ViewProviderMesh::clipMeshCallback(void * ud, SoEventCallback * n)
00585 {
00586
00587 Gui::WaitCursor wc;
00588
00589
00590 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
00591 view->setEditing(false);
00592 view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), clipMeshCallback,ud);
00593 n->setHandled();
00594
00595 SbBool clip_inner;
00596 std::vector<SbVec2f> clPoly = view->getGLPolygon(&clip_inner);
00597 if (clPoly.size() < 3)
00598 return;
00599 if (clPoly.front() != clPoly.back())
00600 clPoly.push_back(clPoly.front());
00601
00602 std::vector<Gui::ViewProvider*> views = view->getViewProvidersOfType(ViewProviderMesh::getClassTypeId());
00603 if (!views.empty()) {
00604 Gui::Application::Instance->activeDocument()->openCommand("Cut");
00605 for (std::vector<Gui::ViewProvider*>::iterator it = views.begin(); it != views.end(); ++it) {
00606 ViewProviderMesh* that = static_cast<ViewProviderMesh*>(*it);
00607 if (that->getEditingMode() > -1) {
00608 that->finishEditing();
00609 that->cutMesh(clPoly, *view, clip_inner);
00610 }
00611 }
00612
00613 Gui::Application::Instance->activeDocument()->commitCommand();
00614
00615 view->render();
00616 }
00617 }
00618
00619 void ViewProviderMesh::partMeshCallback(void * ud, SoEventCallback * cb)
00620 {
00621
00622 Gui::WaitCursor wc;
00623
00624
00625 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(cb->getUserData());
00626 view->setEditing(false);
00627 view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), partMeshCallback,ud);
00628 cb->setHandled();
00629
00630 SbBool clip_inner;
00631 std::vector<SbVec2f> clPoly = view->getGLPolygon(&clip_inner);
00632 if (clPoly.size() < 3)
00633 return;
00634 if (clPoly.front() != clPoly.back())
00635 clPoly.push_back(clPoly.front());
00636
00637
00638 SbVec3f b,n;
00639 view->getNearPlane(b, n);
00640 Base::Vector3f cPoint(b[0],b[1],b[2]), cNormal(n[0],n[1],n[2]);
00641 SoCamera* pCam = view->getCamera();
00642 SbViewVolume vol = pCam->getViewVolume();
00643
00644
00645 std::vector<MeshCore::MeshGeomFacet> aFaces;
00646 if (!ViewProviderMesh::createToolMesh(clPoly, vol, cNormal, aFaces))
00647 Base::Console().Message("The picked polygon seems to have self-overlappings. This could lead to strange results.");
00648
00649 MeshCore::MeshKernel toolMesh;
00650 bool locked = Base::Sequencer().setLocked(true);
00651 toolMesh = aFaces;
00652 Base::Sequencer().setLocked(locked);
00653
00654
00655 Gui::Application::Instance->activeDocument()->openCommand("Split");
00656
00657 try {
00658 std::vector<Gui::ViewProvider*> views = view->getViewProvidersOfType(ViewProviderMesh::getClassTypeId());
00659 for (std::vector<Gui::ViewProvider*>::iterator it = views.begin(); it != views.end(); ++it) {
00660 ViewProviderMesh* that = static_cast<ViewProviderMesh*>(*it);
00661 if (that->getEditingMode() > -1) {
00662 that->finishEditing();
00663 that->splitMesh(toolMesh, cNormal, clip_inner);
00664 }
00665 }
00666 }
00667 catch(...) {
00668
00669 }
00670
00671
00672 Gui::Application::Instance->activeDocument()->commitCommand();
00673 view->render();
00674 }
00675
00676 void ViewProviderMesh::segmMeshCallback(void * ud, SoEventCallback * cb)
00677 {
00678
00679 Gui::WaitCursor wc;
00680
00681
00682 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(cb->getUserData());
00683 view->setEditing(false);
00684 view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), segmMeshCallback,ud);
00685 cb->setHandled();
00686
00687 SbBool clip_inner;
00688 std::vector<SbVec2f> clPoly = view->getGLPolygon(&clip_inner);
00689 if (clPoly.size() < 3)
00690 return;
00691 if (clPoly.front() != clPoly.back())
00692 clPoly.push_back(clPoly.front());
00693
00694
00695 SbVec3f b,n;
00696 view->getNearPlane(b, n);
00697 Base::Vector3f cPoint(b[0],b[1],b[2]), cNormal(n[0],n[1],n[2]);
00698 SoCamera* pCam = view->getCamera();
00699 SbViewVolume vol = pCam->getViewVolume();
00700
00701
00702 std::vector<MeshCore::MeshGeomFacet> aFaces;
00703 if (!ViewProviderMesh::createToolMesh(clPoly, vol, cNormal, aFaces))
00704 Base::Console().Message("The picked polygon seems to have self-overlappings. This could lead to strange results.");
00705
00706 MeshCore::MeshKernel toolMesh;
00707 bool locked = Base::Sequencer().setLocked(true);
00708 toolMesh = aFaces;
00709 Base::Sequencer().setLocked(locked);
00710
00711
00712 Gui::Application::Instance->activeDocument()->openCommand("Segment");
00713
00714 try {
00715 std::vector<Gui::ViewProvider*> views = view->getViewProvidersOfType(ViewProviderMesh::getClassTypeId());
00716 for (std::vector<Gui::ViewProvider*>::iterator it = views.begin(); it != views.end(); ++it) {
00717 ViewProviderMesh* that = static_cast<ViewProviderMesh*>(*it);
00718 if (that->getEditingMode() > -1) {
00719 that->finishEditing();
00720 that->segmentMesh(toolMesh, cNormal, clip_inner);
00721 }
00722 }
00723 }
00724 catch(...) {
00725
00726 }
00727
00728
00729 Gui::Application::Instance->activeDocument()->commitCommand();
00730 view->render();
00731 }
00732
00733 void ViewProviderMesh::selectGLCallback(void * ud, SoEventCallback * n)
00734 {
00735
00736 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
00737 view->setEditing(false);
00738 view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), selectGLCallback,ud);
00739 n->setHandled();
00740
00741 std::vector<SbVec2f> clPoly = view->getGLPolygon();
00742 if (clPoly.size() != 1)
00743 return;
00744 const SoEvent* ev = n->getEvent();
00745
00746 SbVec2f pos = clPoly[0];
00747 float pX,pY; pos.getValue(pX,pY);
00748 const SbVec2s& sz = view->getViewportRegion().getViewportSizePixels();
00749 float fRatio = view->getViewportRegion().getViewportAspectRatio();
00750 if (fRatio > 1.0f) {
00751 pX = (pX - 0.5f) / fRatio + 0.5f;
00752 pos.setValue(pX,pY);
00753 }
00754 else if (fRatio < 1.0f) {
00755 pY = (pY - 0.5f) * fRatio + 0.5f;
00756 pos.setValue(pX,pY);
00757 }
00758
00759 short x1 = (short)(pX * sz[0] + 0.5f);
00760 short y1 = (short)(pY * sz[1] + 0.5f);
00761 SbVec2s loc = ev->getPosition();
00762 short x2 = loc[0];
00763 short y2 = loc[1];
00764
00765 short x = (x1+x2)/2;
00766 short y = (y1+y2)/2;
00767 short w = (x2-x1);
00768 short h = (y2-y1);
00769 if (w<0) w = -w;
00770 if (h<0) h = -h;
00771
00772 std::vector<Gui::ViewProvider*> views;
00773 views = view->getViewProvidersOfType(ViewProviderMesh::getClassTypeId());
00774 for (std::vector<Gui::ViewProvider*>::iterator it = views.begin(); it != views.end(); ++it) {
00775 ViewProviderMesh* that = static_cast<ViewProviderMesh*>(*it);
00776 if (that->getEditingMode() > -1) {
00777 that->finishEditing();
00778 that->selectArea(x, y, w, h, view->getViewportRegion(), view->getCamera());
00779 }
00780 }
00781
00782 view->render();
00783 }
00784
00785 void ViewProviderMesh::getFacetsFromPolygon(const std::vector<SbVec2f>& picked,
00786 Gui::View3DInventorViewer &Viewer,
00787 SbBool inner,
00788 std::vector<unsigned long>& indices) const
00789 {
00790 #if 1
00791 bool ok = true;
00792 SoCamera* cam = Viewer.getCamera();
00793 SbViewVolume vv = cam->getViewVolume();
00794 Gui::ViewVolumeProjection proj(vv);
00795 Base::Polygon2D polygon;
00796 for (std::vector<SbVec2f>::const_iterator it = picked.begin(); it != picked.end(); ++it)
00797 polygon.Add(Base::Vector2D((*it)[0],(*it)[1]));
00798
00799
00800 Mesh::PropertyMeshKernel& meshProp = static_cast<Mesh::Feature*>(pcObject)->Mesh;
00801 MeshCore::MeshAlgorithm cAlg(meshProp.getValue().getKernel());
00802 cAlg.CheckFacets(&proj, polygon, true, indices);
00803 #else
00804
00805 SbVec3f b,n;
00806 Viewer.getNearPlane(b, n);
00807 Base::Vector3f cPoint(b[0],b[1],b[2]), cNormal(n[0],n[1],n[2]);
00808 SoCamera* pCam = Viewer.getCamera();
00809 SbViewVolume vol = pCam->getViewVolume();
00810
00811
00812 std::vector<MeshCore::MeshGeomFacet> aFaces;
00813 bool ok = ViewProviderMesh::createToolMesh(picked, vol, cNormal, aFaces);
00814
00815
00816 Mesh::PropertyMeshKernel& meshProp = static_cast<Mesh::Feature*>(pcObject)->Mesh;
00817
00818
00819 MeshCore::MeshKernel cToolMesh;
00820 bool locked = Base::Sequencer().setLocked(true);
00821 cToolMesh = aFaces;
00822 Base::Sequencer().setLocked(locked);
00823 MeshCore::MeshFacetGrid cGrid(meshProp.getValue().getKernel());
00824 MeshCore::MeshAlgorithm cAlg(meshProp.getValue().getKernel());
00825 cAlg.GetFacetsFromToolMesh(cToolMesh, cNormal, cGrid, indices);
00826 #endif
00827 if (!inner) {
00828
00829 std::vector<unsigned long> complete(meshProp.getValue().countFacets());
00830 std::generate(complete.begin(), complete.end(), Base::iotaGen<unsigned long>(0));
00831 std::sort(indices.begin(), indices.end());
00832 std::vector<unsigned long> complementary;
00833 std::back_insert_iterator<std::vector<unsigned long> > biit(complementary);
00834 std::set_difference(complete.begin(), complete.end(), indices.begin(), indices.end(), biit);
00835 indices = complementary;
00836 }
00837
00838 if (!ok)
00839 Base::Console().Message("The picked polygon seems to have self-overlappings. This could lead to strange results.");
00840 }
00841
00842 std::vector<unsigned long> ViewProviderMesh::getFacetsOfRegion(const SbViewportRegion& select,
00843 const SbViewportRegion& region,
00844 SoCamera* camera) const
00845 {
00846 SoSeparator* root = new SoSeparator();
00847 root->ref();
00848 root->addChild(camera);
00849 root->addChild(const_cast<ViewProviderMesh*>(this)->getCoordNode());
00850 root->addChild(const_cast<ViewProviderMesh*>(this)->getShapeNode());
00851 Gui::SoGLSelectAction gl(region, select);
00852 gl.apply(root);
00853 root->unref();
00854
00855 std::vector<unsigned long> faces;
00856 faces.insert(faces.end(), gl.indices.begin(), gl.indices.end());
00857 return faces;
00858 }
00859
00860 void ViewProviderMesh::panCamera(SoCamera * cam, float aspectratio, const SbPlane & panplane,
00861 const SbVec2f & currpos, const SbVec2f & prevpos)
00862 {
00863 if (cam == NULL) return;
00864 if (currpos == prevpos) return;
00865
00866
00867
00868 SbViewVolume vv = cam->getViewVolume(aspectratio);
00869 SbLine line;
00870 vv.projectPointToLine(currpos, line);
00871 SbVec3f current_planept;
00872 panplane.intersect(line, current_planept);
00873 vv.projectPointToLine(prevpos, line);
00874 SbVec3f old_planept;
00875 panplane.intersect(line, old_planept);
00876
00877
00878
00879 cam->position = cam->position.getValue() - (current_planept - old_planept);
00880 }
00881
00882 void ViewProviderMesh::boxZoom(const SbBox2s& box, const SbViewportRegion & vp, SoCamera* cam)
00883 {
00884 SbViewVolume vv = cam->getViewVolume(vp.getViewportAspectRatio());
00885
00886 short sizeX,sizeY;
00887 box.getSize(sizeX, sizeY);
00888 SbVec2s size = vp.getViewportSizePixels();
00889
00890
00891
00892 if (sizeX == 0 && sizeY == 0)
00893 return;
00894
00895
00896 short xmin,xmax,ymin,ymax;
00897 box.getBounds(xmin,ymin,xmax,ymax);
00898 const SbVec2f center((float) ((xmin+xmax)/2) / (float) SoQtMax((int)(size[0] - 1), 1),
00899 (float) (size[1]-(ymin+ymax)/2) / (float) SoQtMax((int)(size[1] - 1), 1));
00900
00901 SbPlane plane = vv.getPlane(cam->focalDistance.getValue());
00902 panCamera(cam,vp.getViewportAspectRatio(),plane, SbVec2f(0.5,0.5), center);
00903
00904
00905 float scaleX = (float)sizeX/(float)size[0];
00906 float scaleY = (float)sizeY/(float)size[1];
00907 float scale = std::max<float>(scaleX, scaleY);
00908 if (cam && cam->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
00909 float height = static_cast<SoOrthographicCamera*>(cam)->height.getValue() * scale;
00910 static_cast<SoOrthographicCamera*>(cam)->height = height;
00911 }
00912 else if (cam && cam->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
00913 float height = static_cast<SoPerspectiveCamera*>(cam)->heightAngle.getValue() / 2.0f;
00914 height = 2.0f * atan(tan(height) * scale);
00915 static_cast<SoPerspectiveCamera*>(cam)->heightAngle = height;
00916 }
00917 }
00918
00919 std::vector<unsigned long> ViewProviderMesh::getVisibleFacetsAfterZoom(const SbBox2s& rect,
00920 const SbViewportRegion& vp,
00921 SoCamera* camera) const
00922 {
00923
00924
00925 camera = static_cast<SoCamera*>(camera->copy());
00926 boxZoom(rect,vp,camera);
00927 return getVisibleFacets(vp, camera);
00928 }
00929
00930 void ViewProviderMesh::renderGLCallback(void * ud, SoAction * action)
00931 {
00932 if (action->isOfType(SoGLRenderAction::getClassTypeId())) {
00933 ViewProviderMesh* mesh = reinterpret_cast<ViewProviderMesh*>(ud);
00934 Gui::SoVisibleFaceAction fa;
00935 fa.apply(mesh->getRoot());
00936 }
00937 }
00938
00939 std::vector<unsigned long> ViewProviderMesh::getVisibleFacets(const SbViewportRegion& vp,
00940 SoCamera* camera) const
00941 {
00942 const Mesh::PropertyMeshKernel& meshProp = static_cast<Mesh::Feature*>(pcObject)->Mesh;
00943 const Mesh::MeshObject& mesh = meshProp.getValue();
00944 uint32_t count = (uint32_t)mesh.countFacets();
00945
00946 SoSeparator* root = new SoSeparator;
00947 root->ref();
00948 root->addChild(camera);
00949
00950 #if 0
00951 SoCallback* cb = new SoCallback;
00952 cb->setCallback(renderGLCallback, const_cast<ViewProviderMesh*>(this));
00953 root->addChild(cb);
00954 #else
00955 SoLightModel* lm = new SoLightModel();
00956 lm->model = SoLightModel::BASE_COLOR;
00957 root->addChild(lm);
00958 SoMaterial* mat = new SoMaterial();
00959 mat->diffuseColor.setNum(count);
00960 SbColor* diffcol = mat->diffuseColor.startEditing();
00961 for (uint32_t i=0; i<count; i++) {
00962 float t;
00963 diffcol[i].setPackedValue(i<<8,t);
00964 }
00965
00966 mat->diffuseColor.finishEditing();
00967 SoMaterialBinding* bind = new SoMaterialBinding();
00968 bind->value = SoMaterialBinding::PER_FACE;
00969 root->addChild(mat);
00970 root->addChild(bind);
00971 #endif
00972 root->addChild(this->getCoordNode());
00973 root->addChild(this->getShapeNode());
00974
00975 Gui::SoFCOffscreenRenderer& renderer = Gui::SoFCOffscreenRenderer::instance();
00976 renderer.setViewportRegion(vp);
00977 renderer.setBackgroundColor(SbColor(0.0f, 0.0f, 0.0f));
00978
00979 QImage img;
00980 renderer.render(root);
00981 renderer.writeToImage(img);
00982 root->unref();
00983
00984 int width = img.width();
00985 int height = img.height();
00986 QRgb color=0;
00987 std::vector<unsigned long> faces;
00988 for (int y = 0; y < height; y++) {
00989 for (int x = 0; x < width; x++) {
00990 QRgb rgb = img.pixel(x,y);
00991 rgb = rgb-(0xff << 24);
00992 if (rgb != 0 && rgb != color) {
00993 color = rgb;
00994 faces.push_back((unsigned long)rgb);
00995 }
00996 }
00997 }
00998
00999 std::sort(faces.begin(), faces.end());
01000 faces.erase(std::unique(faces.begin(), faces.end()), faces.end());
01001
01002 return faces;
01003 }
01004
01005 void ViewProviderMesh::cutMesh(const std::vector<SbVec2f>& picked,
01006 Gui::View3DInventorViewer &Viewer, SbBool inner)
01007 {
01008
01009 std::vector<unsigned long> indices;
01010 getFacetsFromPolygon(picked, Viewer, inner, indices);
01011
01012
01013 Mesh::PropertyMeshKernel& meshProp = static_cast<Mesh::Feature*>(pcObject)->Mesh;
01014
01015
01016 meshProp.deleteFacetIndices(indices);
01017 pcObject->purgeTouched();
01018 }
01019
01020 void ViewProviderMesh::splitMesh(const MeshCore::MeshKernel& toolMesh, const Base::Vector3f& normal, SbBool clip_inner)
01021 {
01022
01023 Mesh::PropertyMeshKernel& meshProp = static_cast<Mesh::Feature*>(pcObject)->Mesh;
01024 const MeshCore::MeshKernel& meshPropKernel = meshProp.getValue().getKernel();
01025
01026
01027 std::vector<unsigned long> indices;
01028 MeshCore::MeshFacetGrid cGrid(meshPropKernel);
01029 MeshCore::MeshAlgorithm cAlg(meshPropKernel);
01030 cAlg.GetFacetsFromToolMesh(toolMesh, normal, cGrid, indices);
01031 if (!clip_inner) {
01032
01033 std::vector<unsigned long> complete(meshPropKernel.CountFacets());
01034 std::generate(complete.begin(), complete.end(), Base::iotaGen<unsigned long>(0));
01035 std::sort(indices.begin(), indices.end());
01036 std::vector<unsigned long> complementary;
01037 std::back_insert_iterator<std::vector<unsigned long> > biit(complementary);
01038 std::set_difference(complete.begin(), complete.end(), indices.begin(), indices.end(), biit);
01039 indices = complementary;
01040 }
01041
01042
01043 Mesh::MeshObject* kernel = meshProp.getValue().meshFromSegment(indices);
01044 meshProp.deleteFacetIndices(indices);
01045 Mesh::Feature* splitMesh = static_cast<Mesh::Feature*>(App::GetApplication().getActiveDocument()
01046 ->addObject("Mesh::Feature",pcObject->getNameInDocument()));
01047
01048 splitMesh->Mesh.setValuePtr(kernel);
01049 static_cast<Mesh::Feature*>(pcObject)->purgeTouched();
01050 }
01051
01052 void ViewProviderMesh::segmentMesh(const MeshCore::MeshKernel& toolMesh, const Base::Vector3f& normal, SbBool clip_inner)
01053 {
01054
01055 Mesh::PropertyMeshKernel& meshProp = static_cast<Mesh::Feature*>(pcObject)->Mesh;
01056 const MeshCore::MeshKernel& meshPropKernel = meshProp.getValue().getKernel();
01057
01058
01059 std::vector<unsigned long> indices;
01060 MeshCore::MeshFacetGrid cGrid(meshPropKernel);
01061 MeshCore::MeshAlgorithm cAlg(meshPropKernel);
01062 cAlg.GetFacetsFromToolMesh(toolMesh, normal, cGrid, indices);
01063 if (!clip_inner) {
01064
01065 std::vector<unsigned long> complete(meshPropKernel.CountFacets());
01066 std::generate(complete.begin(), complete.end(), Base::iotaGen<unsigned long>(0));
01067 std::sort(indices.begin(), indices.end());
01068 std::vector<unsigned long> complementary;
01069 std::back_insert_iterator<std::vector<unsigned long> > biit(complementary);
01070 std::set_difference(complete.begin(), complete.end(), indices.begin(), indices.end(), biit);
01071 indices = complementary;
01072 }
01073
01074 meshProp.createSegment(indices);
01075 static_cast<Mesh::Feature*>(pcObject)->purgeTouched();
01076 }
01077
01078 void ViewProviderMesh::faceInfoCallback(void * ud, SoEventCallback * n)
01079 {
01080 const SoMouseButtonEvent * mbe = (SoMouseButtonEvent *)n->getEvent();
01081 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
01082
01083
01084 n->getAction()->setHandled();
01085 if (mbe->getButton() == SoMouseButtonEvent::BUTTON2 && mbe->getState() == SoButtonEvent::UP) {
01086 n->setHandled();
01087
01088 QMenu menu;
01089 QAction* cl = menu.addAction(QObject::tr("Leave info mode"));
01090 QAction* id = menu.exec(QCursor::pos());
01091 if (cl == id) {
01092 view->setEditing(false);
01093 view->getWidget()->setCursor(QCursor(Qt::ArrowCursor));
01094 view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), faceInfoCallback,ud);
01095 }
01096 }
01097 else if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::DOWN) {
01098 const SoPickedPoint * point = n->getPickedPoint();
01099 if (point == NULL) {
01100 Base::Console().Message("No facet picked.\n");
01101 return;
01102 }
01103
01104 n->setHandled();
01105
01106
01107
01108 Gui::ViewProvider* vp = static_cast<Gui::ViewProvider*>(view->getViewProviderByPath(point->getPath()));
01109 if (!vp || !vp->getTypeId().isDerivedFrom(ViewProviderMesh::getClassTypeId()))
01110 return;
01111 ViewProviderMesh* that = static_cast<ViewProviderMesh*>(vp);
01112 const SoDetail* detail = point->getDetail(that->getShapeNode());
01113 if ( detail && detail->getTypeId() == SoFaceDetail::getClassTypeId() ) {
01114
01115 unsigned long uFacet = ((SoFaceDetail*)detail)->getFaceIndex();
01116 that->faceInfo(uFacet);
01117 Gui::Flag* flag = new Gui::Flag;
01118 flag->setText(QObject::tr("Index: %1").arg(uFacet));
01119 flag->setOrigin(point->getPoint());
01120 view->addFlag(flag, Gui::FlagLayout::TopRight);
01121 }
01122 }
01123 }
01124
01125 void ViewProviderMesh::fillHoleCallback(void * ud, SoEventCallback * n)
01126 {
01127 const SoMouseButtonEvent * mbe = (SoMouseButtonEvent *)n->getEvent();
01128 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
01129
01130
01131 n->getAction()->setHandled();
01132 if (mbe->getButton() == SoMouseButtonEvent::BUTTON2 && mbe->getState() == SoButtonEvent::UP) {
01133 n->setHandled();
01134
01135 QMenu menu;
01136 QAction* cl = menu.addAction(QObject::tr("Leave hole-filling mode"));
01137 QAction* id = menu.exec(QCursor::pos());
01138 if (cl == id) {
01139 view->setEditing(false);
01140 view->getWidget()->setCursor(QCursor(Qt::ArrowCursor));
01141 view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), fillHoleCallback,ud);
01142 }
01143 }
01144 else if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::DOWN) {
01145 const SoPickedPoint * point = n->getPickedPoint();
01146 if (point == NULL) {
01147 Base::Console().Message("No facet picked.\n");
01148 return;
01149 }
01150
01151 n->setHandled();
01152
01153
01154
01155 Gui::ViewProvider* vp = static_cast<Gui::ViewProvider*>(view->getViewProviderByPath(point->getPath()));
01156 if (!vp || !vp->getTypeId().isDerivedFrom(ViewProviderMesh::getClassTypeId()))
01157 return;
01158 ViewProviderMesh* that = static_cast<ViewProviderMesh*>(vp);
01159 const SoDetail* detail = point->getDetail(that->getShapeNode());
01160 if ( detail && detail->getTypeId() == SoFaceDetail::getClassTypeId() ) {
01161
01162 unsigned long uFacet = ((SoFaceDetail*)detail)->getFaceIndex();
01163 that->fillHole(uFacet);
01164 }
01165 }
01166 }
01167
01168 void ViewProviderMesh::markPartCallback(void * ud, SoEventCallback * n)
01169 {
01170
01171 if (n->getEvent()->isOfType(SoMouseButtonEvent::getClassTypeId())) {
01172 const SoMouseButtonEvent * mbe = static_cast<const SoMouseButtonEvent*>(n->getEvent());
01173 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
01174
01175
01176 n->getAction()->setHandled();
01177 if (mbe->getButton() == SoMouseButtonEvent::BUTTON2 && mbe->getState() == SoButtonEvent::UP) {
01178 n->setHandled();
01179
01180 QMenu menu;
01181 QAction* cl = menu.addAction(QObject::tr("Leave removal mode"));
01182 QAction* rm = menu.addAction(QObject::tr("Delete selected faces"));
01183 QAction* cf = menu.addAction(QObject::tr("Clear selected faces"));
01184 QAction* id = menu.exec(QCursor::pos());
01185 if (cl == id) {
01186 view->setEditing(false);
01187 view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), markPartCallback,ud);
01188
01189 std::vector<ViewProvider*> views = view->getViewProvidersOfType(ViewProviderMesh::getClassTypeId());
01190 for (std::vector<ViewProvider*>::iterator it = views.begin(); it != views.end(); ++it) {
01191 static_cast<ViewProviderMesh*>(*it)->clearSelection();
01192 }
01193 }
01194 else if (cf == id) {
01195 std::vector<ViewProvider*> views = view->getViewProvidersOfType(ViewProviderMesh::getClassTypeId());
01196 for (std::vector<ViewProvider*>::iterator it = views.begin(); it != views.end(); ++it) {
01197 static_cast<ViewProviderMesh*>(*it)->clearSelection();
01198 }
01199 }
01200 else if (rm == id) {
01201 Gui::Application::Instance->activeDocument()->openCommand("Delete");
01202 std::vector<ViewProvider*> views = view->getViewProvidersOfType(ViewProviderMesh::getClassTypeId());
01203 for (std::vector<ViewProvider*>::iterator it = views.begin(); it != views.end(); ++it) {
01204 static_cast<ViewProviderMesh*>(*it)->deleteSelection();
01205 }
01206 view->render();
01207 Gui::Application::Instance->activeDocument()->commitCommand();
01208 }
01209 }
01210 else if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::DOWN) {
01211 const SoPickedPoint * point = n->getPickedPoint();
01212 if (point == NULL) {
01213 Base::Console().Message("No facet picked.\n");
01214 return;
01215 }
01216
01217 n->setHandled();
01218
01219
01220
01221 Gui::ViewProvider* vp = static_cast<Gui::ViewProvider*>(view->getViewProviderByPath(point->getPath()));
01222 if (!vp || !vp->getTypeId().isDerivedFrom(ViewProviderMesh::getClassTypeId()))
01223 return;
01224 ViewProviderMesh* that = static_cast<ViewProviderMesh*>(vp);
01225 const SoDetail* detail = point->getDetail(that->getShapeNode());
01226 if ( detail && detail->getTypeId() == SoFaceDetail::getClassTypeId() ) {
01227
01228 unsigned long uFacet = static_cast<const SoFaceDetail*>(detail)->getFaceIndex();
01229 that->selectComponent(uFacet);
01230 }
01231 }
01232 }
01233 }
01234
01235 void ViewProviderMesh::faceInfo(unsigned long uFacet)
01236 {
01237 Mesh::Feature* fea = reinterpret_cast<Mesh::Feature*>(this->getObject());
01238 const MeshCore::MeshKernel& rKernel = fea->Mesh.getValue().getKernel();
01239 const MeshCore::MeshFacetArray& facets = rKernel.GetFacets();
01240 if (uFacet < facets.size()) {
01241 MeshCore::MeshFacet face = facets[uFacet];
01242 MeshCore::MeshGeomFacet tria = rKernel.GetFacet(face);
01243 Base::Console().Message("Mesh: %s Facet %ld: Points: <%ld, %ld, %ld>, Neighbours: <%ld, %ld, %ld>\n"
01244 "Triangle: <[%.6f, %.6f, %.6f], [%.6f, %.6f, %.6f], [%.6f, %.6f, %.6f]>\n", fea->getNameInDocument(), uFacet,
01245 face._aulPoints[0], face._aulPoints[1], face._aulPoints[2],
01246 face._aulNeighbours[0], face._aulNeighbours[1], face._aulNeighbours[2],
01247 tria._aclPoints[0].x, tria._aclPoints[0].y, tria._aclPoints[0].z,
01248 tria._aclPoints[1].x, tria._aclPoints[1].y, tria._aclPoints[1].z,
01249 tria._aclPoints[2].x, tria._aclPoints[2].y, tria._aclPoints[2].z);
01250 }
01251 }
01252
01253 void ViewProviderMesh::fillHole(unsigned long uFacet)
01254 {
01255
01256 Base::Reference<ParameterGrp> hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("Mod/Mesh");
01257 int level = (int)hGrp->GetInt("FillHoleLevel", 2);
01258
01259
01260 std::list<unsigned long> aBorder;
01261 Mesh::Feature* fea = reinterpret_cast<Mesh::Feature*>(this->getObject());
01262 const MeshCore::MeshKernel& rKernel = fea->Mesh.getValue().getKernel();
01263 MeshCore::MeshRefPointToFacets cPt2Fac(rKernel);
01264 MeshCore::MeshAlgorithm meshAlg(rKernel);
01265 meshAlg.GetMeshBorder(uFacet, aBorder);
01266 std::vector<unsigned long> boundary(aBorder.begin(), aBorder.end());
01267 std::list<std::vector<unsigned long> > boundaries;
01268 boundaries.push_back(boundary);
01269 meshAlg.SplitBoundaryLoops(boundaries);
01270
01271 std::vector<MeshCore::MeshFacet> newFacets;
01272 std::vector<Base::Vector3f> newPoints;
01273 unsigned long numberOfOldPoints = rKernel.CountPoints();
01274 for (std::list<std::vector<unsigned long> >::iterator it = boundaries.begin(); it != boundaries.end(); ++it) {
01275 if (it->size() < 3)
01276 continue;
01277 boundary = *it;
01278 MeshCore::MeshFacetArray faces;
01279 MeshCore::MeshPointArray points;
01280 MeshCore::QuasiDelaunayTriangulator cTria;
01281 if (meshAlg.FillupHole(boundary, cTria, faces, points, level, &cPt2Fac)) {
01282 if (boundary.front() == boundary.back())
01283 boundary.pop_back();
01284
01285 unsigned long countBoundaryPoints = boundary.size();
01286 unsigned long countDifference = points.size() - countBoundaryPoints;
01287 if (countDifference > 0) {
01288 MeshCore::MeshPointArray::_TIterator pt = points.begin() + countBoundaryPoints;
01289 for (unsigned long i=0; i<countDifference; i++, pt++) {
01290 boundary.push_back(numberOfOldPoints++);
01291 newPoints.push_back(*pt);
01292 }
01293 }
01294 for (MeshCore::MeshFacetArray::_TIterator kt = faces.begin(); kt != faces.end(); ++kt ) {
01295 kt->_aulPoints[0] = boundary[kt->_aulPoints[0]];
01296 kt->_aulPoints[1] = boundary[kt->_aulPoints[1]];
01297 kt->_aulPoints[2] = boundary[kt->_aulPoints[2]];
01298 newFacets.push_back(*kt);
01299 }
01300 }
01301 }
01302
01303 if (newFacets.empty())
01304 return;
01305
01306
01307 Gui::Application::Instance->activeDocument()->openCommand("Fill hole");
01308 fea->Mesh.append(newFacets, newPoints);
01309 Gui::Application::Instance->activeDocument()->commitCommand();
01310 }
01311
01312 void ViewProviderMesh::selectFacet(unsigned long facet)
01313 {
01314 std::vector<unsigned long> selection;
01315 selection.push_back(facet);
01316
01317 const Mesh::MeshObject& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue();
01318 rMesh.addFacetsToSelection(selection);
01319
01320
01321 pcMatBinding->value = SoMaterialBinding::PER_FACE;
01322 int uCtFacets = (int)rMesh.countFacets();
01323
01324 if (uCtFacets != pcShapeMaterial->diffuseColor.getNum()) {
01325 highlightSelection();
01326 }
01327 else {
01328 pcShapeMaterial->diffuseColor.set1Value(facet,1.0f,0.0f,0.0f);
01329 }
01330 }
01331
01332 void ViewProviderMesh::deselectFacet(unsigned long facet)
01333 {
01334 std::vector<unsigned long> selection;
01335 selection.push_back(facet);
01336
01337 const Mesh::MeshObject& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue();
01338 rMesh.removeFacetsFromSelection(selection);
01339
01340
01341 pcMatBinding->value = SoMaterialBinding::PER_FACE;
01342 int uCtFacets = (int)rMesh.countFacets();
01343
01344 if (uCtFacets != pcShapeMaterial->diffuseColor.getNum()) {
01345 highlightSelection();
01346 }
01347 else {
01348 App::Color c = ShapeColor.getValue();
01349 pcShapeMaterial->diffuseColor.set1Value(facet,c.r,c.g,c.b);
01350 }
01351 }
01352
01353 void ViewProviderMesh::selectComponent(unsigned long uFacet)
01354 {
01355 std::vector<unsigned long> selection;
01356 selection.push_back(uFacet);
01357
01358 MeshCore::MeshTopFacetVisitor clVisitor(selection);
01359 const Mesh::MeshObject& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue();
01360 const MeshCore::MeshKernel& rKernel = rMesh.getKernel();
01361 MeshCore::MeshAlgorithm(rKernel).ResetFacetFlag(MeshCore::MeshFacet::VISIT);
01362 rKernel.VisitNeighbourFacets(clVisitor, uFacet);
01363 rMesh.addFacetsToSelection(selection);
01364
01365
01366 highlightSelection();
01367 }
01368
01369 void ViewProviderMesh::deselectComponent(unsigned long uFacet)
01370 {
01371 std::vector<unsigned long> selection;
01372 selection.push_back(uFacet);
01373
01374 MeshCore::MeshTopFacetVisitor clVisitor(selection);
01375 const Mesh::MeshObject& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue();
01376 const MeshCore::MeshKernel& rKernel = rMesh.getKernel();
01377 MeshCore::MeshAlgorithm(rKernel).ResetFacetFlag(MeshCore::MeshFacet::VISIT);
01378 rKernel.VisitNeighbourFacets(clVisitor, uFacet);
01379 rMesh.removeFacetsFromSelection(selection);
01380
01381
01382 highlightSelection();
01383 }
01384
01385 void ViewProviderMesh::setSelection(const std::vector<unsigned long>& indices)
01386 {
01387 const Mesh::MeshObject& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue();
01388 rMesh.clearFacetSelection();
01389 rMesh.addFacetsToSelection(indices);
01390
01391
01392 highlightSelection();
01393 }
01394
01395 void ViewProviderMesh::addSelection(const std::vector<unsigned long>& indices)
01396 {
01397 const Mesh::MeshObject& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue();
01398 rMesh.addFacetsToSelection(indices);
01399
01400
01401 highlightSelection();
01402 }
01403
01404 void ViewProviderMesh::removeSelection(const std::vector<unsigned long>& indices)
01405 {
01406 const Mesh::MeshObject& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue();
01407 rMesh.removeFacetsFromSelection(indices);
01408
01409
01410 highlightSelection();
01411 }
01412
01413 void ViewProviderMesh::clearSelection()
01414 {
01415 const Mesh::MeshObject& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue();
01416 rMesh.clearFacetSelection();
01417 unhighlightSelection();
01418 }
01419
01420 void ViewProviderMesh::deleteSelection()
01421 {
01422 std::vector<unsigned long> indices;
01423 Mesh::PropertyMeshKernel& meshProp = static_cast<Mesh::Feature*>(pcObject)->Mesh;
01424 const Mesh::MeshObject& rMesh = meshProp.getValue();
01425 rMesh.getFacetsFromSelection(indices);
01426 if (!indices.empty()) {
01427 unhighlightSelection();
01428
01429 Mesh::MeshObject* pMesh = meshProp.startEditing();
01430 pMesh->deleteFacets(indices);
01431 meshProp.finishEditing();
01432 pcObject->purgeTouched();
01433 }
01434 }
01435
01436 void ViewProviderMesh::selectArea(short x, short y, short w, short h,
01437 const SbViewportRegion& region,
01438 SoCamera* camera)
01439 {
01440 SbViewportRegion vp;
01441 vp.setViewportPixels (x, y, w, h);
01442 std::vector<unsigned long> faces = getFacetsOfRegion(vp, region, camera);
01443
01444 const Mesh::MeshObject& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue();
01445 rMesh.addFacetsToSelection(faces);
01446
01447
01448 highlightSelection();
01449 }
01450
01451 void ViewProviderMesh::highlightSelection()
01452 {
01453 std::vector<unsigned long> selection;
01454 const Mesh::MeshObject& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue();
01455 rMesh.getFacetsFromSelection(selection);
01456 if (selection.empty()) {
01457
01458
01459 return;
01460 }
01461
01462
01463 pcMatBinding->value = SoMaterialBinding::PER_FACE;
01464 App::Color c = ShapeColor.getValue();
01465 int uCtFacets = (int)rMesh.countFacets();
01466 pcShapeMaterial->diffuseColor.setNum(uCtFacets);
01467
01468 SbColor* cols = pcShapeMaterial->diffuseColor.startEditing();
01469 for (int i=0; i<uCtFacets; i++)
01470 cols[i].setValue(c.r,c.g,c.b);
01471 for (std::vector<unsigned long>::iterator it = selection.begin(); it != selection.end(); ++it)
01472 cols[*it].setValue(1.0f,0.0f,0.0f);
01473 pcShapeMaterial->diffuseColor.finishEditing();
01474 }
01475
01476 void ViewProviderMesh::unhighlightSelection()
01477 {
01478 App::Color c = ShapeColor.getValue();
01479 pcMatBinding->value = SoMaterialBinding::OVERALL;
01480 pcShapeMaterial->diffuseColor.setNum(1);
01481 pcShapeMaterial->diffuseColor.setValue(c.r,c.g,c.b);
01482 }
01483
01484
01485
01486 PROPERTY_SOURCE(MeshGui::ViewProviderIndexedFaceSet, MeshGui::ViewProviderMesh)
01487
01488 ViewProviderIndexedFaceSet::ViewProviderIndexedFaceSet()
01489 {
01490 }
01491
01492 ViewProviderIndexedFaceSet::~ViewProviderIndexedFaceSet()
01493 {
01494 }
01495
01500 void ViewProviderIndexedFaceSet::attach(App::DocumentObject *pcFeat)
01501 {
01502 ViewProviderMesh::attach(pcFeat);
01503
01504 pcMeshCoord = new SoCoordinate3;
01505 pcHighlight->addChild(pcMeshCoord);
01506
01507 pcMeshFaces = new SoFCIndexedFaceSet;
01508 pcHighlight->addChild(pcMeshFaces);
01509
01510
01511 Base::Reference<ParameterGrp> hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("Mod/Mesh");
01512 int size = hGrp->GetInt("RenderTriangleLimit", -1);
01513 if (size > 0) static_cast<SoFCIndexedFaceSet*>(pcMeshFaces)->renderTriangleLimit = (unsigned int)(pow(10.0f,size));
01514 }
01515
01516 void ViewProviderIndexedFaceSet::updateData(const App::Property* prop)
01517 {
01518 Gui::ViewProviderGeometryObject::updateData(prop);
01519 if (prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) {
01520 ViewProviderMeshBuilder builder;
01521 builder.createMesh(prop, pcMeshCoord, pcMeshFaces);
01522 showOpenEdges(OpenEdges.getValue());
01523 highlightSelection();
01524 }
01525 }
01526
01527 void ViewProviderIndexedFaceSet::showOpenEdges(bool show)
01528 {
01529 if (pcOpenEdge) {
01530
01531 pcRoot->removeChild(pcOpenEdge);
01532 pcOpenEdge = 0;
01533 }
01534
01535 if (show) {
01536 pcOpenEdge = new SoSeparator();
01537 pcOpenEdge->addChild(pcLineStyle);
01538 pcOpenEdge->addChild(pOpenColor);
01539
01540 pcOpenEdge->addChild(pcMeshCoord);
01541 SoIndexedLineSet* lines = new SoIndexedLineSet;
01542 pcOpenEdge->addChild(lines);
01543
01544
01545 pcRoot->addChild(pcOpenEdge);
01546
01547
01548 int index=0;
01549 const MeshCore::MeshKernel& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue().getKernel();
01550 const MeshCore::MeshFacetArray& rFaces = rMesh.GetFacets();
01551 for (MeshCore::MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it) {
01552 for (int i=0; i<3; i++) {
01553 if (it->_aulNeighbours[i] == ULONG_MAX) {
01554 lines->coordIndex.set1Value(index++,it->_aulPoints[i]);
01555 lines->coordIndex.set1Value(index++,it->_aulPoints[(i+1)%3]);
01556 lines->coordIndex.set1Value(index++,SO_END_LINE_INDEX);
01557 }
01558 }
01559 }
01560 }
01561 }
01562
01563 SoShape* ViewProviderIndexedFaceSet::getShapeNode() const
01564 {
01565 return this->pcMeshFaces;
01566 }
01567
01568 SoNode* ViewProviderIndexedFaceSet::getCoordNode() const
01569 {
01570 return this->pcMeshCoord;
01571 }
01572
01573
01574
01575 PROPERTY_SOURCE(MeshGui::ViewProviderMeshObject, MeshGui::ViewProviderMesh)
01576
01577 ViewProviderMeshObject::ViewProviderMeshObject()
01578 {
01579 }
01580
01581 ViewProviderMeshObject::~ViewProviderMeshObject()
01582 {
01583 }
01584
01585 void ViewProviderMeshObject::attach(App::DocumentObject *pcFeat)
01586 {
01587 ViewProviderMesh::attach(pcFeat);
01588
01589 pcMeshNode = new SoFCMeshObjectNode;
01590 pcHighlight->addChild(pcMeshNode);
01591
01592 pcMeshShape = new SoFCMeshObjectShape;
01593 pcHighlight->addChild(pcMeshShape);
01594
01595
01596 Base::Reference<ParameterGrp> hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("Mod/Mesh");
01597 int size = hGrp->GetInt("RenderTriangleLimit", -1);
01598 if (size > 0) pcMeshShape->renderTriangleLimit = (unsigned int)(pow(10.0f,size));
01599 }
01600
01601 void ViewProviderMeshObject::updateData(const App::Property* prop)
01602 {
01603 Gui::ViewProviderGeometryObject::updateData(prop);
01604 if (prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) {
01605 const Mesh::PropertyMeshKernel* mesh = static_cast<const Mesh::PropertyMeshKernel*>(prop);
01606 this->pcMeshNode->mesh.setValue(mesh->getValuePtr());
01607
01608 this->pcMeshShape->touch();
01609 }
01610 }
01611
01612 void ViewProviderMeshObject::showOpenEdges(bool show)
01613 {
01614 if (pcOpenEdge) {
01615
01616 pcRoot->removeChild(pcOpenEdge);
01617 pcOpenEdge = 0;
01618 }
01619
01620 if (show) {
01621 pcOpenEdge = new SoSeparator();
01622 pcOpenEdge->addChild(pcLineStyle);
01623 pcOpenEdge->addChild(pOpenColor);
01624
01625 pcOpenEdge->addChild(pcMeshNode);
01626 pcOpenEdge->addChild(new SoFCMeshObjectBoundary);
01627
01628
01629 pcRoot->addChild(pcOpenEdge);
01630 }
01631 }
01632
01633 SoShape* ViewProviderMeshObject::getShapeNode() const
01634 {
01635 return this->pcMeshShape;
01636 }
01637
01638 SoNode* ViewProviderMeshObject::getCoordNode() const
01639 {
01640 return this->pcMeshNode;
01641 }