Mod/ReverseEngineering/Gui/Command.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 #ifndef _PreComp_
00026 #endif
00027
00028 #include <sstream>
00029
00030 #include <Mod/Part/App/TopoShape.h>
00031 #include <Mod/Part/App/PartFeature.h>
00032 #include <Mod/Mesh/App/MeshFeature.h>
00033 #include <Mod/Mesh/App/Core/Approximation.h>
00034
00035 #include <Gui/Application.h>
00036 #include <Gui/Command.h>
00037 #include <Gui/MainWindow.h>
00038 #include <Gui/FileDialog.h>
00039 #include <Gui/Selection.h>
00040
00041 #include "../App/ApproxSurface.h"
00042
00043 using namespace std;
00044
00045 DEF_STD_CMD_A(CmdApproxSurface);
00046
00047 CmdApproxSurface::CmdApproxSurface()
00048 : Command("Reen_ApproxSurface")
00049 {
00050 sAppModule = "Reen";
00051 sGroup = QT_TR_NOOP("Reverse Engineering");
00052 sMenuText = QT_TR_NOOP("Approximate surface...");
00053 sToolTipText = QT_TR_NOOP("Approximate a B-Spline surface");
00054 sWhatsThis = sToolTipText;
00055 sStatusTip = sToolTipText;
00056 sPixmap = "actions/FitSurface";
00057 }
00058
00059 void CmdApproxSurface::activated(int iMsg)
00060 {
00061 std::vector<App::DocumentObject*> obj = Gui::Selection().getObjectsOfType(Mesh::Feature::getClassTypeId());
00062 const Mesh::MeshObject& mesh = static_cast<Mesh::Feature*>(obj[0])->Mesh.getValue();
00063 if (mesh.countSegments() > 0) {
00064 const Mesh::Segment& segm = mesh.getSegment(0);
00065 const std::vector<unsigned long>& inds = segm.getIndices();
00066 MeshCore::MeshFacetIterator f_iter(mesh.getKernel());
00067 std::set<unsigned long> points;
00068 for (std::vector<unsigned long>::const_iterator it = inds.begin(); it != inds.end(); ++it) {
00069 f_iter.Set(*it);
00070 MeshCore::MeshFacet face = f_iter.GetIndices();
00071 points.insert(face._aulPoints[0]);
00072 points.insert(face._aulPoints[1]);
00073 points.insert(face._aulPoints[2]);
00074 }
00075
00076 std::stringstream str;
00077 str << "__points=[]" << std::endl;
00078 for (std::set<unsigned long>::iterator it=points.begin(); it != points.end(); ++it) {
00079 Mesh::MeshPoint p = mesh.getPoint(*it);
00080 str << "__points.append((" << p.x << "," << p.y << "," << p.z << "))" << std::endl;
00081 }
00082
00083 str << "import ReverseEngineering" << std::endl;
00084 str << "__spline = ReverseEngineering.approxSurface(__points)" << std::endl;
00085 str << "App.ActiveDocument.addObject(\"Part::Feature\",\"Surface\").Shape"
00086 "=__spline.toShape(0.0,1.0,0.0,1.0)" << std::endl;
00087 str << "App.ActiveDocument.recompute()" << std::endl;
00088 str << "del __points" << std::endl;
00089 str << "del __spline" << std::endl;
00090
00091 openCommand("Fit surface");
00092 doCommand(Gui::Command::Doc, str.str().c_str());
00093 commitCommand();
00094 updateActive();
00095 }
00096 }
00097
00098 bool CmdApproxSurface::isActive(void)
00099 {
00100 if (getSelection().countObjectsOfType(Mesh::Feature::getClassTypeId()) == 1)
00101 return true;
00102 return false;
00103 }
00104
00105 DEF_STD_CMD_A(CmdApproxPlane);
00106
00107 CmdApproxPlane::CmdApproxPlane()
00108 : Command("Reen_ApproxPlane")
00109 {
00110 sAppModule = "Reen";
00111 sGroup = QT_TR_NOOP("Reverse Engineering");
00112 sMenuText = QT_TR_NOOP("Approximate plane...");
00113 sToolTipText = QT_TR_NOOP("Approximate a plane");
00114 sWhatsThis = sToolTipText;
00115 sStatusTip = sToolTipText;
00116 }
00117
00118 void CmdApproxPlane::activated(int iMsg)
00119 {
00120 std::vector<App::GeoFeature*> obj = Gui::Selection().getObjectsOfType<App::GeoFeature>();
00121 for (std::vector<App::GeoFeature*>::iterator it = obj.begin(); it != obj.end(); ++it) {
00122 std::map<std::string, App::Property*> Map;
00123 (*it)->getPropertyMap(Map);
00124 for (std::map<std::string, App::Property*>::iterator jt = Map.begin(); jt != Map.end(); ++jt) {
00125 if (jt->second->getTypeId().isDerivedFrom(App::PropertyComplexGeoData::getClassTypeId())) {
00126 std::vector<Base::Vector3d> aPoints;
00127 std::vector<Data::ComplexGeoData::Facet> aTopo;
00128 static_cast<App::PropertyComplexGeoData*>(jt->second)->getFaces(aPoints, aTopo,0.01f);
00129
00130 std::vector<Base::Vector3f> aData;
00131 aData.reserve(aPoints.size());
00132 for (std::vector<Base::Vector3d>::iterator jt = aPoints.begin(); jt != aPoints.end(); ++jt)
00133 aData.push_back(Base::toVector<float>(*jt));
00134 MeshCore::PlaneFit fit;
00135 fit.AddPoints(aData);
00136 float sigma = fit.Fit();
00137 Base::Vector3f base = fit.GetBase();
00138 Base::Vector3f norm = fit.GetNormal();
00139
00140 Base::Console().Message("RMS value for plane fit with %ld points: %.4f\n", aData.size(), sigma);
00141 Base::Console().Message(" Plane base(%.4f, %.4f, %.4f)\n", base.x, base.y, base.z);
00142 Base::Console().Message(" Plane normal(%.4f, %.4f, %.4f)\n", norm.x, norm.y, norm.z);
00143
00144 std::stringstream str;
00145 str << "import Part" << std::endl;
00146 str << "from FreeCAD import Base" << std::endl;
00147 str << "Part.show(Part.makePlane("
00148 << 10 << ", " << 10 << ", "
00149 << "Base.Vector("
00150 << base.x << ", " << base.y << ", " << base.z << "), "
00151 << "Base.Vector("
00152 << norm.x << ", " << norm.y << ", " << norm.z << ")))" << std::endl;
00153
00154 openCommand("Fit plane");
00155 doCommand(Gui::Command::Doc, str.str().c_str());
00156 commitCommand();
00157 updateActive();
00158 }
00159 }
00160 }
00161 }
00162
00163 bool CmdApproxPlane::isActive(void)
00164 {
00165 if (getSelection().countObjectsOfType(App::GeoFeature::getClassTypeId()) == 1)
00166 return true;
00167 return false;
00168 }
00169
00170 void CreateReverseEngineeringCommands(void)
00171 {
00172 Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
00173 rcCmdMgr.addCommand(new CmdApproxSurface());
00174 rcCmdMgr.addCommand(new CmdApproxPlane());
00175 }