Exemple #1
0
 virtual std::vector<float> getParameter(FitParameter::Points pts) const {
     std::vector<float> values;
     MeshCore::PlaneFit fit;
     fit.AddPoints(pts);
     if (fit.Fit() < FLOAT_MAX) {
         Base::Vector3f base = fit.GetBase();
         Base::Vector3f axis = fit.GetNormal();
         values.push_back(base.x);
         values.push_back(base.y);
         values.push_back(base.z);
         values.push_back(axis.x);
         values.push_back(axis.y);
         values.push_back(axis.z);
     }
     return values;
 }
Exemple #2
0
void CmdApproxPlane::activated(int iMsg)
{
    std::vector<App::GeoFeature*> obj = Gui::Selection().getObjectsOfType<App::GeoFeature>();
    for (std::vector<App::GeoFeature*>::iterator it = obj.begin(); it != obj.end(); ++it) {
        std::map<std::string, App::Property*> Map;
        (*it)->getPropertyMap(Map);
        for (std::map<std::string, App::Property*>::iterator jt = Map.begin(); jt != Map.end(); ++jt) {
            if (jt->second->getTypeId().isDerivedFrom(App::PropertyComplexGeoData::getClassTypeId())) {
                std::vector<Base::Vector3d> aPoints;
                std::vector<Data::ComplexGeoData::Facet> aTopo;
                static_cast<App::PropertyComplexGeoData*>(jt->second)->getFaces(aPoints, aTopo,0.01f);

                // get a reference normal for the plane fit
                Base::Vector3f refNormal(0,0,0);
                if (!aTopo.empty()) {
                    Data::ComplexGeoData::Facet f = aTopo.front();
                    Base::Vector3d v1 = aPoints[f.I2] - aPoints[f.I1];
                    Base::Vector3d v2 = aPoints[f.I3] - aPoints[f.I1];
                    refNormal = Base::convertTo<Base::Vector3f>(v1 % v2);
                }

                std::vector<Base::Vector3f> aData;
                aData.reserve(aPoints.size());
                for (std::vector<Base::Vector3d>::iterator jt = aPoints.begin(); jt != aPoints.end(); ++jt)
                    aData.push_back(Base::toVector<float>(*jt));
                MeshCore::PlaneFit fit;
                fit.AddPoints(aData);
                float sigma = fit.Fit();
                Base::Vector3f base = fit.GetBase();
                Base::Vector3f dirU = fit.GetDirU();
                Base::Vector3f dirV = fit.GetDirV();
                Base::Vector3f norm = fit.GetNormal();

                // if the dot product of the reference with the plane normal is negative
                // a flip must be done
                if (refNormal * norm < 0) {
                    norm = -norm;
                    dirU = -dirU;
                }

                float width, length;
                fit.Dimension(width, length);

                // move to the corner point
                base = base - (0.5f * length * dirU + 0.5f * width * dirV);

                Base::CoordinateSystem cs;
                cs.setPosition(Base::convertTo<Base::Vector3d>(base));
                cs.setAxes(Base::convertTo<Base::Vector3d>(norm),
                           Base::convertTo<Base::Vector3d>(dirU));
                Base::Placement pm = Base::CoordinateSystem().displacement(cs);
                double q0, q1, q2, q3;
                pm.getRotation().getValue(q0, q1, q2, q3);

                Base::Console().Log("RMS value for plane fit with %lu points: %.4f\n", aData.size(), sigma);
                Base::Console().Log("  Plane base(%.4f, %.4f, %.4f)\n", base.x, base.y, base.z);
                Base::Console().Log("  Plane normal(%.4f, %.4f, %.4f)\n", norm.x, norm.y, norm.z);

                std::stringstream str;
                str << "from FreeCAD import Base" << std::endl;
                str << "App.ActiveDocument.addObject('Part::Plane','Plane_fit')" << std::endl;
                str << "App.ActiveDocument.ActiveObject.Length = " << length << std::endl;
                str << "App.ActiveDocument.ActiveObject.Width = " << width << std::endl;
                str << "App.ActiveDocument.ActiveObject.Placement = Base.Placement("
                    << "Base.Vector(" << base.x << "," << base.y << "," << base.z << "),"
                    << "Base.Rotation(" << q0 << "," << q1 << "," << q2 << "," << q3 << "))" << std::endl;
                
                openCommand("Fit plane");
                doCommand(Gui::Command::Doc, str.str().c_str());
                commitCommand(); 
                updateActive();
            }
        }
    }
}