00001 /*************************************************************************** 00002 * Copyright (c) 2006 Werner Mayer <wmayer[at]users.sourceforge.net> * 00003 * * 00004 * This file is part of the FreeCAD CAx development system. * 00005 * * 00006 * This library is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU Library General Public * 00008 * License as published by the Free Software Foundation; either * 00009 * version 2 of the License, or (at your option) any later version. * 00010 * * 00011 * This library is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU Library General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Library General Public * 00017 * License along with this library; see the file COPYING.LIB. If not, * 00018 * write to the Free Software Foundation, Inc., 59 Temple Place, * 00019 * Suite 330, Boston, MA 02111-1307, USA * 00020 * * 00021 ***************************************************************************/ 00022 00023 00024 #include "PreCompiled.h" 00025 00026 #ifndef _PreComp_ 00027 # include <algorithm> 00028 # include <Inventor/SoPickedPoint.h> 00029 # include <Inventor/details/SoFaceDetail.h> 00030 # include <Inventor/nodes/SoBaseColor.h> 00031 # include <Inventor/nodes/SoCoordinate3.h> 00032 # include <Inventor/nodes/SoDrawStyle.h> 00033 # include <Inventor/nodes/SoIndexedLineSet.h> 00034 # include <Inventor/nodes/SoMaterial.h> 00035 # include <Inventor/nodes/SoMaterialBinding.h> 00036 # include <Inventor/nodes/SoPolygonOffset.h> 00037 # include <Inventor/nodes/SoShapeHints.h> 00038 # include <Inventor/nodes/SoOrthographicCamera.h> 00039 # include <Inventor/nodes/SoTransform.h> 00040 # include <Inventor/nodes/SoSeparator.h> 00041 # include <Inventor/events/SoMouseButtonEvent.h> 00042 # include <QAction> 00043 # include <QMenu> 00044 #endif 00045 00047 #include <Base/Console.h> 00048 #include <Base/Exception.h> 00049 #include <Base/Sequencer.h> 00050 #include <Base/Tools2D.h> 00051 #include <Base/ViewProj.h> 00052 00053 #include <App/Document.h> 00054 #include <App/PropertyLinks.h> 00055 00056 #include <Gui/Application.h> 00057 #include <Gui/Command.h> 00058 #include <Gui/Document.h> 00059 #include <Gui/SoFCSelection.h> 00060 #include <Gui/MainWindow.h> 00061 #include <Gui/Selection.h> 00062 #include <Gui/WaitCursor.h> 00063 #include <Gui/Window.h> 00064 #include <Gui/Flag.h> 00065 #include <Gui/View3DInventor.h> 00066 #include <Gui/View3DInventorViewer.h> 00067 00068 #include <Mod/Mesh/App/Core/Algorithm.h> 00069 #include <Mod/Mesh/App/Core/Evaluation.h> 00070 #include <Mod/Mesh/App/Core/Grid.h> 00071 #include <Mod/Mesh/App/Core/Iterator.h> 00072 #include <Mod/Mesh/App/Core/MeshIO.h> 00073 #include <Mod/Mesh/App/Core/MeshKernel.h> 00074 #include <Mod/Mesh/App/Core/Triangulation.h> 00075 #include <Mod/Mesh/App/Core/Visitor.h> 00076 #include <Mod/Mesh/App/Mesh.h> 00077 #include <Mod/Mesh/App/MeshFeature.h> 00078 #include <Mod/Mesh/App/MeshProperties.h> 00079 00080 #include "ViewProviderMeshFaceSet.h" 00081 #include "SoFCMeshObject.h" 00082 #include "SoFCIndexedFaceSet.h" 00083 00084 00085 using namespace MeshGui; 00086 00087 00088 PROPERTY_SOURCE(MeshGui::ViewProviderMeshFaceSet, MeshGui::ViewProviderMesh) 00089 00090 ViewProviderMeshFaceSet::ViewProviderMeshFaceSet() 00091 { 00092 directRendering = false; 00093 triangleCount = 2500000; 00094 00095 pcMeshNode = new SoFCMeshObjectNode; 00096 pcMeshNode->ref(); 00097 pcMeshShape = new SoFCMeshObjectShape; 00098 pcMeshShape->ref(); 00099 pcMeshCoord = new SoCoordinate3; 00100 pcMeshCoord->ref(); 00101 pcMeshFaces = new SoFCIndexedFaceSet; 00102 pcMeshFaces->ref(); 00103 } 00104 00105 ViewProviderMeshFaceSet::~ViewProviderMeshFaceSet() 00106 { 00107 pcMeshNode->unref(); 00108 pcMeshShape->unref(); 00109 pcMeshCoord->unref(); 00110 pcMeshFaces->unref(); 00111 } 00112 00113 void ViewProviderMeshFaceSet::attach(App::DocumentObject *pcFeat) 00114 { 00115 ViewProviderMesh::attach(pcFeat); 00116 00117 pcHighlight->addChild(pcMeshCoord); 00118 pcHighlight->addChild(pcMeshFaces); 00119 00120 // read the threshold from the preferences 00121 Base::Reference<ParameterGrp> hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("Mod/Mesh"); 00122 int size = hGrp->GetInt("RenderTriangleLimit", -1); 00123 if (size > 0) { 00124 pcMeshShape->renderTriangleLimit = (unsigned int)(pow(10.0f,size)); 00125 static_cast<SoFCIndexedFaceSet*>(pcMeshFaces)->renderTriangleLimit = (unsigned int)(pow(10.0f,size)); 00126 } 00127 } 00128 00129 void ViewProviderMeshFaceSet::updateData(const App::Property* prop) 00130 { 00131 Gui::ViewProviderGeometryObject::updateData(prop); 00132 if (prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { 00133 const Mesh::MeshObject* mesh = static_cast<const Mesh::PropertyMeshKernel*>(prop)->getValuePtr(); 00134 00135 bool direct = (mesh->countFacets() > this->triangleCount); 00136 if (direct) { 00137 this->pcMeshNode->mesh.setValue(mesh); 00138 // Needs to update internal bounding box caches 00139 this->pcMeshShape->touch(); 00140 pcMeshCoord->point.setNum(0); 00141 pcMeshFaces->coordIndex.setNum(0); 00142 } 00143 else { 00144 ViewProviderMeshBuilder builder; 00145 builder.createMesh(prop, pcMeshCoord, pcMeshFaces); 00146 } 00147 00148 if (direct != directRendering) { 00149 directRendering = direct; 00150 pcHighlight->removeAllChildren(); 00151 00152 if (directRendering) { 00153 pcHighlight->addChild(pcMeshNode); 00154 pcHighlight->addChild(pcMeshShape); 00155 } 00156 else { 00157 pcHighlight->addChild(pcMeshCoord); 00158 pcHighlight->addChild(pcMeshFaces); 00159 } 00160 } 00161 00162 showOpenEdges(OpenEdges.getValue()); 00163 highlightSelection(); 00164 } 00165 } 00166 00167 void ViewProviderMeshFaceSet::showOpenEdges(bool show) 00168 { 00169 if (pcOpenEdge) { 00170 // remove the node and destroy the data 00171 pcRoot->removeChild(pcOpenEdge); 00172 pcOpenEdge = 0; 00173 } 00174 00175 if (show) { 00176 pcOpenEdge = new SoSeparator(); 00177 pcOpenEdge->addChild(pcLineStyle); 00178 pcOpenEdge->addChild(pOpenColor); 00179 00180 if (directRendering) { 00181 pcOpenEdge->addChild(pcMeshNode); 00182 pcOpenEdge->addChild(new SoFCMeshObjectBoundary); 00183 } 00184 else { 00185 pcOpenEdge->addChild(pcMeshCoord); 00186 SoIndexedLineSet* lines = new SoIndexedLineSet; 00187 pcOpenEdge->addChild(lines); 00188 00189 // Build up the lines with indices to the list of vertices 'pcMeshCoord' 00190 int index=0; 00191 const MeshCore::MeshKernel& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue().getKernel(); 00192 const MeshCore::MeshFacetArray& rFaces = rMesh.GetFacets(); 00193 for (MeshCore::MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it) { 00194 for (int i=0; i<3; i++) { 00195 if (it->_aulNeighbours[i] == ULONG_MAX) { 00196 lines->coordIndex.set1Value(index++,it->_aulPoints[i]); 00197 lines->coordIndex.set1Value(index++,it->_aulPoints[(i+1)%3]); 00198 lines->coordIndex.set1Value(index++,SO_END_LINE_INDEX); 00199 } 00200 } 00201 } 00202 } 00203 00204 // add to the highlight node 00205 pcRoot->addChild(pcOpenEdge); 00206 } 00207 } 00208 00209 SoShape* ViewProviderMeshFaceSet::getShapeNode() const 00210 { 00211 if (directRendering) 00212 return this->pcMeshShape; 00213 return this->pcMeshFaces; 00214 } 00215 00216 SoNode* ViewProviderMeshFaceSet::getCoordNode() const 00217 { 00218 if (directRendering) 00219 return this->pcMeshNode; 00220 return this->pcMeshCoord; 00221 }