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 <Inventor/nodes/SoBaseColor.h>
00028 # include <Inventor/nodes/SoDrawStyle.h>
00029 # include <Inventor/nodes/SoMaterial.h>
00030 # include <Inventor/nodes/SoShapeHints.h>
00031 # include <Inventor/nodes/SoOrthographicCamera.h>
00032 # include <qmessagebox.h>
00033 #endif
00034
00036 #include <Base/Console.h>
00037 #include <Base/Exception.h>
00038 #include <Base/Sequencer.h>
00039 #include <Base/Tools2D.h>
00040 #include <Base/ViewProj.h>
00041
00042 #include <App/Document.h>
00043 #include <App/PropertyLinks.h>
00044
00045 #include <Gui/Application.h>
00046 #include <Gui/Command.h>
00047 #include <Gui/Document.h>
00048 #include <Gui/SoFCSelection.h>
00049 #include <Gui/MainWindow.h>
00050 #include <Gui/MouseModel.h>
00051 #include <Gui/Selection.h>
00052 #include <Gui/Window.h>
00053 #include <Gui/View3DInventor.h>
00054 #include <Gui/View3DInventorViewer.h>
00055
00056 #include <Mod/Mesh/App/Core/Algorithm.h>
00057 #include <Mod/Mesh/App/Core/Evaluation.h>
00058 #include <Mod/Mesh/App/Core/Grid.h>
00059 #include <Mod/Mesh/App/Core/Iterator.h>
00060 #include <Mod/Mesh/App/Core/MeshIO.h>
00061 #include <Mod/Mesh/App/Core/Visitor.h>
00062 #include <Mod/Mesh/App/Mesh.h>
00063 #include <Mod/Mesh/App/MeshFeature.h>
00064 #include <Mod/Mesh/Gui/SoFCMeshNode.h>
00065
00066 #include "ViewProvider.h"
00067 #include "ViewProviderMeshNode.h"
00068
00069
00070 using namespace MeshGui;
00071
00072
00073 App::PropertyFloatConstraint::Constraints ViewProviderMeshNode::floatRange = {1.0f,64.0f,1.0f};
00074
00075 PROPERTY_SOURCE(MeshGui::ViewProviderMeshNode, Gui::ViewProviderGeometryObject)
00076
00077 ViewProviderMeshNode::ViewProviderMeshNode() : pcOpenEdge(0), m_bEdit(false)
00078 {
00079 ADD_PROPERTY(LineWidth,(2.0f));
00080 LineWidth.setConstraints(&floatRange);
00081 ADD_PROPERTY(PointSize,(2.0f));
00082 PointSize.setConstraints(&floatRange);
00083 ADD_PROPERTY(OpenEdges,(false));
00084
00085 pOpenColor = new SoBaseColor();
00086 setOpenEdgeColorFrom(ShapeColor.getValue());
00087 pOpenColor->ref();
00088
00089 pcLineStyle = new SoDrawStyle();
00090 pcLineStyle->ref();
00091 pcLineStyle->style = SoDrawStyle::LINES;
00092 pcLineStyle->lineWidth = LineWidth.getValue();
00093
00094 pcPointStyle = new SoDrawStyle();
00095 pcPointStyle->ref();
00096 pcPointStyle->style = SoDrawStyle::POINTS;
00097 pcPointStyle->pointSize = PointSize.getValue();
00098
00099
00100 Base::Reference<ParameterGrp> hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("Mod/Mesh");
00101 App::Color color = ShapeColor.getValue();
00102 unsigned long current = color.getPackedValue();
00103 unsigned long setting = hGrp->GetUnsigned("MeshColor", current);
00104 if ( current != setting )
00105 {
00106 color.setPackedValue((uint32_t)setting);
00107 ShapeColor.setValue(color);
00108 }
00109 }
00110
00111 ViewProviderMeshNode::~ViewProviderMeshNode()
00112 {
00113 pOpenColor->unref();
00114 pcLineStyle->unref();
00115 pcPointStyle->unref();
00116 }
00117
00118 void ViewProviderMeshNode::onChanged(const App::Property* prop)
00119 {
00120 if ( prop == &LineWidth ) {
00121 pcLineStyle->lineWidth = LineWidth.getValue();
00122 } else if ( prop == &PointSize ) {
00123 pcPointStyle->pointSize = PointSize.getValue();
00124 } else if ( prop == &OpenEdges ) {
00125 showOpenEdges( OpenEdges.getValue() );
00126 } else {
00127
00128 if ( prop == &ShapeColor ) {
00129 setOpenEdgeColorFrom(ShapeColor.getValue());
00130 } else if ( prop == &ShapeMaterial ) {
00131 setOpenEdgeColorFrom(ShapeMaterial.getValue().diffuseColor);
00132 }
00133 ViewProviderGeometryObject::onChanged(prop);
00134 }
00135 }
00136
00137 void ViewProviderMeshNode::setOpenEdgeColorFrom( const App::Color& c )
00138 {
00139 float r=1.0f-c.r; r = r < 0.5f ? 0.0f : 1.0f;
00140 float g=1.0f-c.g; g = g < 0.5f ? 0.0f : 1.0f;
00141 float b=1.0f-c.b; b = b < 0.5f ? 0.0f : 1.0f;
00142 pOpenColor->rgb.setValue(r, g, b);
00143 }
00144
00145 void ViewProviderMeshNode::attach(App::DocumentObject *pcFeat)
00146 {
00147 ViewProviderGeometryObject::attach(pcFeat);
00148
00149
00150 const Mesh::Feature* meshFeature = dynamic_cast<Mesh::Feature*>(pcFeat);
00151 MeshGui::SoFCMeshNode* mesh = new MeshGui::SoFCMeshNode();
00152 mesh->setMesh(meshFeature->Mesh.getValuePtr());
00153 pcHighlight->addChild(mesh);
00154
00155
00156
00157 SoGroup* pcFlatRoot = new SoGroup();
00158
00159
00160 Base::Reference<ParameterGrp> hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("Mod/Mesh");
00161 bool twoSide = hGrp->GetBool("TwoSideRendering", true);
00162 if ( twoSide )
00163 {
00164
00165 SoShapeHints * flathints = new SoShapeHints;
00166 flathints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
00167 flathints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE;
00168 pcFlatRoot->addChild(flathints);
00169 }
00170
00171 pcFlatRoot->addChild(pcShapeMaterial);
00172 pcFlatRoot->addChild(pcHighlight);
00173 addDisplayMaskMode(pcFlatRoot, "Flat");
00174
00175
00176 SoGroup* pcPointRoot = new SoGroup();
00177 pcPointRoot->addChild(pcPointStyle);
00178 pcPointRoot->addChild(pcFlatRoot);
00179 addDisplayMaskMode(pcPointRoot, "Point");
00180
00181
00182 SoLightModel* pcLightModel = new SoLightModel();
00183 pcLightModel->model = SoLightModel::BASE_COLOR;
00184 SoGroup* pcWireRoot = new SoGroup();
00185 pcWireRoot->addChild(pcLineStyle);
00186 pcWireRoot->addChild(pcLightModel);
00187 pcWireRoot->addChild(pcShapeMaterial);
00188 pcWireRoot->addChild(pcHighlight);
00189 addDisplayMaskMode(pcWireRoot, "Wireframe");
00190
00191
00192 SoGroup* pcFlatWireRoot = new SoGroup();
00193 pcFlatWireRoot->addChild(pcFlatRoot);
00194 pcFlatWireRoot->addChild(pcWireRoot);
00195 addDisplayMaskMode(pcFlatWireRoot, "FlatWireframe");
00196 }
00197
00198 void ViewProviderMeshNode::updateData(const App::Property*)
00199 {
00200
00201 pcHighlight->touch();
00202 }
00203
00204 QIcon ViewProviderMeshNode::getIcon() const
00205 {
00206 const char * Mesh_Feature_xpm[] = {
00207 "16 16 4 1",
00208 ". c None",
00209 "# c #000000",
00210 "s c #BEC2FC",
00211 "g c #00FF00",
00212 ".......##.......",
00213 "....#######.....",
00214 "..##ggg#ggg#....",
00215 "##ggggg#gggg##..",
00216 "#g#ggg#gggggg##.",
00217 "#gg#gg#gggg###s.",
00218 "#gg#gg#gg##gg#s.",
00219 "#ggg#####ggg#ss.",
00220 "#gggg##gggg#ss..",
00221 ".#g##g#gggg#s...",
00222 ".##ggg#ggg#ss...",
00223 ".##gggg#g#ss....",
00224 "..s#####g#s.....",
00225 "....sss##ss.....",
00226 "........ss......",
00227 "................"};
00228 QPixmap px(Mesh_Feature_xpm);
00229 return px;
00230 }
00231
00232 void ViewProviderMeshNode::setDisplayMode(const char* ModeName)
00233 {
00234 if ( strcmp("Shaded",ModeName)==0 )
00235 setDisplayMaskMode("Flat");
00236 else if ( strcmp("Points",ModeName)==0 )
00237 setDisplayMaskMode("Point");
00238 else if ( strcmp("Shaded+Wireframe",ModeName)==0 )
00239 setDisplayMaskMode("FlatWireframe");
00240 else if ( strcmp("Wireframe",ModeName)==0 )
00241 setDisplayMaskMode("Wireframe");
00242
00243 ViewProviderGeometryObject::setDisplayMode( ModeName );
00244 }
00245
00246 std::vector<std::string> ViewProviderMeshNode::getDisplayModes(void) const
00247 {
00248 std::vector<std::string> StrList;
00249
00250
00251 StrList.push_back("Shaded");
00252 StrList.push_back("Wireframe");
00253 StrList.push_back("Shaded+Wireframe");
00254 StrList.push_back("Points");
00255
00256 return StrList;
00257 }
00258
00259 bool ViewProviderMeshNode::setEdit(int ModNum)
00260 {
00261 if ( m_bEdit ) return true;
00262 m_bEdit = true;
00263 return true;
00264 }
00265
00266 void ViewProviderMeshNode::unsetEdit(void)
00267 {
00268 m_bEdit = false;
00269 }
00270
00271 const char* ViewProviderMeshNode::getEditModeName(void)
00272 {
00273 return "Polygon picking";
00274 }
00275
00276 bool ViewProviderMeshNode::handleEvent(const SoEvent * const ev,Gui::View3DInventorViewer &Viewer)
00277 {
00278 if ( m_bEdit )
00279 {
00280 unsetEdit();
00281 std::vector<SbVec2f> clPoly = Viewer.getPickedPolygon();
00282 if ( clPoly.size() < 3 )
00283 return true;
00284 if ( clPoly.front() != clPoly.back() )
00285 clPoly.push_back(clPoly.front());
00286
00287
00288 SbVec3f b,n;
00289 Viewer.getNearPlane(b, n);
00290 Base::Vector3f cPoint(b[0],b[1],b[2]), cNormal(n[0],n[1],n[2]);
00291 SoCamera* pCam = Viewer.getCamera();
00292 SbViewVolume vol = pCam->getViewVolume ();
00293
00294
00295 std::vector<MeshCore::MeshGeomFacet> aFaces;
00296 bool ok = ViewProviderMesh::createToolMesh( clPoly, vol, cNormal, aFaces );
00297
00298
00299 Mesh::PropertyMeshKernel& meshProp = ((Mesh::Feature*)pcObject)->Mesh;
00300
00301
00302 std::vector<unsigned long> indices;
00303 MeshCore::MeshKernel cToolMesh;
00304 cToolMesh = aFaces;
00305 MeshCore::MeshFacetGrid cGrid(meshProp.getValue().getKernel());
00306 MeshCore::MeshAlgorithm cAlg(meshProp.getValue().getKernel());
00307 cAlg.GetFacetsFromToolMesh(cToolMesh, cNormal, cGrid, indices);
00308 meshProp.deleteFacetIndices( indices );
00309
00310
00311
00312
00313
00314
00315
00316
00317 Viewer.render();
00318 if ( !ok )
00319
00320 Base::Console().Message("The picked polygon seems to have self-overlappings. This could lead to strange results.");
00321 }
00322
00323 return false;
00324 }
00325
00326 void ViewProviderMeshNode::showOpenEdges(bool show)
00327 {
00328 #if 1
00329 if ( show ) {
00330 pcOpenEdge = new SoSeparator();
00331 pcOpenEdge->addChild(pcLineStyle);
00332 pcOpenEdge->addChild(pOpenColor);
00333
00334 const Mesh::Feature* meshFeature = dynamic_cast<Mesh::Feature*>(pcObject);
00335 MeshGui::SoFCMeshOpenEdge* mesh = new MeshGui::SoFCMeshOpenEdge();
00336 mesh->setMesh(meshFeature->Mesh.getValuePtr());
00337 pcOpenEdge->addChild(mesh);
00338
00339
00340 pcHighlight->addChild(pcOpenEdge);
00341 } else if (pcOpenEdge) {
00342
00343 pcHighlight->removeChild(pcOpenEdge);
00344 pcOpenEdge = 0;
00345 }
00346 #else
00347 if ( show ) {
00348 pcOpenEdge = new SoSeparator();
00349 pcOpenEdge->addChild(pcLineStyle);
00350 pcOpenEdge->addChild(pOpenColor);
00351 SoCoordinate3* points = new SoCoordinate3();
00352 pcOpenEdge->addChild(points);
00353 SoLineSet* lines = new SoLineSet();
00354 pcOpenEdge->addChild(lines);
00355
00356 pcHighlight->addChild(pcOpenEdge);
00357
00358
00359 int index=0;
00360 const MeshCore::MeshKernel& rMesh = dynamic_cast<Mesh::Feature*>(pcObject)->getMesh();
00361 const MeshCore::MeshFacetArray& rFaces = rMesh.GetFacets();
00362 const MeshCore::MeshPointArray& rPoint = rMesh.GetPoints();
00363
00364
00365 int ctEdges=0;
00366 for ( MeshCore::MeshFacetArray::_TConstIterator jt = rFaces.begin(); jt != rFaces.end(); ++jt ) {
00367 for ( int i=0; i<3; i++ ) {
00368 if ( jt->_aulNeighbours[i] == ULONG_MAX ) {
00369 ctEdges++;
00370 }
00371 }
00372 }
00373
00374
00375 points->enableNotify(false);
00376 lines->enableNotify(false);
00377
00378 points->point.setNum(2*ctEdges);
00379 lines->numVertices.setNum(ctEdges);
00380 for ( MeshCore::MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it ) {
00381 for ( int i=0; i<3; i++ ) {
00382 if ( it->_aulNeighbours[i] == ULONG_MAX ) {
00383 const MeshCore::MeshPoint& cP0 = rPoint[it->_aulPoints[i]];
00384 const MeshCore::MeshPoint& cP1 = rPoint[it->_aulPoints[(i+1)%3]];
00385 points->point.set1Value(index++, cP0.x, cP0.y, cP0.z);
00386 points->point.set1Value(index++, cP1.x, cP1.y, cP1.z);
00387 lines->numVertices.set1Value(index/2-1,2);
00388 }
00389 }
00390 }
00391
00392
00393 points->enableNotify(true);
00394 lines->enableNotify(true);
00395 points->touch();
00396 lines->touch();
00397 } else {
00398
00399 pcHighlight->removeChild(pcOpenEdge);
00400 pcOpenEdge = 0;
00401 }
00402 #endif
00403 }