int main(int argc, char *argv[]) { if(argc < 2) { std::cout << "Usage: " << std::endl; std::cout << "extractStlPoints [InputSTLFile]" << std::endl; return 1; } char* inputFileName = argv[1]; TopoDS_Shape stlShape; std::cout << "Reading STL file " << inputFileName << " ..." << std::flush; StlAPI::Read(stlShape,inputFileName); std::cout << "done."; Handle_TColgp_HArray1OfPnt extractedPoints = StlPointsExtractor::extractVerticesFromTopoDSShape(stlShape); WriteCoordinatesToFile::writeCoordinatesToFile("stlOutput.txt",extractedPoints->Array1()); return 0; }
int main(int argc, char *argv[]) { //Create a circle like before gp_Pnt centerPoint(2.5,2.5,0); gp_Dir normalDirection(0.0,0.0,1.0); gp_Dir xDirection(1.0,0.0,0.0); gp_Ax2 axis(centerPoint,normalDirection,xDirection); //Creating the circle gp_Circ circle(axis,2.5); Standard_Integer resolution = 20; //Here, an array of gp_Pnt is allocated, with 500 elements //Note that the indexing runs from 1 to 500, instead of the //standard convention of 0-499 TColgp_Array1OfPnt pointsOnCircle(1,resolution); //Distribute the points and write them out to a file PointOnCurveDistribution::distributePointsOnCurve(circle,pointsOnCircle,0.0,2.0*PI,resolution); WriteCoordinatesToFile::writeCoordinatesToFile("chapter3points.txt",pointsOnCircle); //Sum the area of the small triangles, to get an approximate area //The for loop builds triangles with two corners on the circumference //and the center of the circle as third point double totalArea = 0.0; for(Standard_Integer i=1;i<=resolution;i++) { gp_Pnt firstPntOfTriangle = pointsOnCircle.Value(i); gp_Pnt secondPntOfTriangle; if(i != resolution) { secondPntOfTriangle = pointsOnCircle.Value(i+1); } else { //If we are at the end of the array, take the first point //because of periodicity secondPntOfTriangle = pointsOnCircle.Value(1); } gp_Pnt thirdPntOfTriangle = centerPoint; //A Handle (like a smart pointer) is built to an array of points Handle_TColgp_HArray1OfPnt trianglePointsArray = new TColgp_HArray1OfPnt(1,3); trianglePointsArray->ChangeValue(1) = firstPntOfTriangle; trianglePointsArray->ChangeValue(2) = secondPntOfTriangle; trianglePointsArray->ChangeValue(3) = thirdPntOfTriangle; totalArea += AreaCalculations::calculateTriangleArea(trianglePointsArray); } std::cout << "Polygonized area: " << totalArea << std::endl; std::cout << "Reference area: " << circle.Area() << std::endl; std::cout << "Error " << fabs(totalArea-circle.Area())/circle.Area() << std::endl; return 0; }
Standard_Boolean CircleFitCostFunction::Value(const math_Vector& X, Standard_Real& F) { double sum = 0.0; for(Standard_Integer i = myPointsToFitOnto->Lower();i<=myPointsToFitOnto->Upper();i++) { double pxMinusCx = myPointsToFitOnto->Value(i).X()-X(1); double pyMinusCy = myPointsToFitOnto->Value(i).Y()-X(2); sum += (pxMinusCx*pxMinusCx+pyMinusCy*pyMinusCy-X(3)*X(3))*(pxMinusCx*pxMinusCx+pyMinusCy*pyMinusCy-X(3)*X(3)); } F = sum; return Standard_True; }
LeastSquaresFitting::InitialGuessForLeastSquaresFitting LeastSquaresFitting::findInitialGuess(const Handle_TColgp_HArray1OfPnt& points) { //Compute center of gravity for point set double cx=0.0; double cy=0.0; for(Standard_Integer i=points->Lower();i<=points->Upper();i++) { cx += points->Value(i).X(); cy += points->Value(i).Y(); } cx /= points->Length(); cy /= points->Length(); gp_Pnt centerPoint(cx,cy,0.0); //Compute average radius double averageRadius = 0.0; for(Standard_Integer i=points->Lower();i<=points->Upper();i++) { averageRadius += centerPoint.Distance(points->Value(i)); } averageRadius /= points->Length(); return InitialGuessForLeastSquaresFitting(centerPoint,averageRadius); }
PyObject* BSplineCurvePy::interpolate(PyObject *args) { PyObject* obj; double tol3d = Precision::Approximation(); PyObject* periodic = Py_False; PyObject* t1=0; PyObject* t2=0; if (!PyArg_ParseTuple(args, "O|O!dO!O!",&obj, &PyBool_Type, &periodic, &tol3d, &Base::VectorPy::Type, &t1, &Base::VectorPy::Type, &t2)) return 0; try { Py::Sequence list(obj); Handle_TColgp_HArray1OfPnt interpolationPoints = new TColgp_HArray1OfPnt(1, list.size()); Standard_Integer index = 1; for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { Py::Vector v(*it); Base::Vector3d pnt = v.toVector(); interpolationPoints->SetValue(index++, gp_Pnt(pnt.x,pnt.y,pnt.z)); } if (interpolationPoints->Length() < 2) { Standard_Failure::Raise("not enough points given"); } GeomAPI_Interpolate aBSplineInterpolation(interpolationPoints, PyObject_IsTrue(periodic) ? Standard_True : Standard_False, tol3d); if (t1 && t2) { Base::Vector3d v1 = Py::Vector(t1,false).toVector(); Base::Vector3d v2 = Py::Vector(t2,false).toVector(); gp_Vec initTangent(v1.x,v1.y,v1.z), finalTangent(v2.x,v2.y,v2.z); aBSplineInterpolation.Load(initTangent, finalTangent); } aBSplineInterpolation.Perform(); if (aBSplineInterpolation.IsDone()) { Handle_Geom_BSplineCurve aBSplineCurve(aBSplineInterpolation.Curve()); this->getGeomBSplineCurvePtr()->setHandle(aBSplineCurve); Py_Return; } else { Standard_Failure::Raise("failed to interpolate points"); return 0; // goes to the catch block } } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); std::string err = e->GetMessageString(); if (err.empty()) err = e->DynamicType()->Name(); PyErr_SetString(PartExceptionOCCError, err.c_str()); return 0; } }
double calculateTriangleArea(const Handle_TColgp_HArray1OfPnt triangleCorners) { //We compute the area of the triangle using the determinant approach //First, allocate a 3 by 3 matrix for the calculation math_Matrix matrixForAreaCalculation(0,2,0,2); //Then fill it with the coordinates of the triangle corners matrixForAreaCalculation(0,0) = triangleCorners->Value(1).X(); matrixForAreaCalculation(0,1) = triangleCorners->Value(1).Y(); matrixForAreaCalculation(0,2) = 1.0; matrixForAreaCalculation(1,0) = triangleCorners->Value(2).X(); matrixForAreaCalculation(1,1) = triangleCorners->Value(2).Y(); matrixForAreaCalculation(1,2) = 1.0; matrixForAreaCalculation(2,0) = triangleCorners->Value(3).X(); matrixForAreaCalculation(2,1) = triangleCorners->Value(3).Y(); matrixForAreaCalculation(2,2) = 1.0; double area = 0.5 * matrixForAreaCalculation.Determinant(); return area; }
Standard_Boolean CircleFitCostFunction::Gradient(const math_Vector& X, math_Vector& G) { double g0 = 0.0; double g1 = 0.0; double g2 = 0.0; for(Standard_Integer i = myPointsToFitOnto->Lower();i<=myPointsToFitOnto->Upper();i++) { double pxMinusCx = myPointsToFitOnto->Value(i).X()-X(1); double pyMinusCy = myPointsToFitOnto->Value(i).Y()-X(2); double distance = pxMinusCx*pxMinusCx+pyMinusCy*pyMinusCy-X(3)*X(3); g0 += pxMinusCx*distance; g1 += pyMinusCy*distance; g2 += distance; } G(1) = -4.0*g0; G(2) = -4.0*g1; G(3) = -4.0*X(3)*g2; return Standard_True; }
PyObject* BSplineCurvePy::interpolate(PyObject *args, PyObject *kwds) { PyObject* obj; PyObject* par = 0; double tol3d = Precision::Approximation(); PyObject* periodic = Py_False; PyObject* t1 = 0; PyObject* t2 = 0; PyObject* ts = 0; PyObject* fl = 0; PyObject* scale = Py_True; static char* kwds_interp[] = {"Points", "PeriodicFlag", "Tolerance", "InitialTangent", "FinalTangent", "Tangents", "TangentFlags", "Parameters", "Scale", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O!dO!O!OOOO!",kwds_interp, &obj, &PyBool_Type, &periodic, &tol3d, &Base::VectorPy::Type, &t1, &Base::VectorPy::Type, &t2, &ts, &fl, &par, &PyBool_Type, &scale)) return 0; try { Py::Sequence list(obj); Handle_TColgp_HArray1OfPnt interpolationPoints = new TColgp_HArray1OfPnt(1, list.size()); Standard_Integer index = 1; for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { Py::Vector v(*it); Base::Vector3d pnt = v.toVector(); interpolationPoints->SetValue(index++, gp_Pnt(pnt.x,pnt.y,pnt.z)); } if (interpolationPoints->Length() < 2) { Standard_Failure::Raise("not enough points given"); } Handle_TColStd_HArray1OfReal parameters; if (par) { Py::Sequence plist(par); parameters = new TColStd_HArray1OfReal(1, plist.size()); Standard_Integer pindex = 1; for (Py::Sequence::iterator it = plist.begin(); it != plist.end(); ++it) { Py::Float f(*it); parameters->SetValue(pindex++, static_cast<double>(f)); } } std::unique_ptr<GeomAPI_Interpolate> aBSplineInterpolation; if (parameters.IsNull()) { aBSplineInterpolation.reset(new GeomAPI_Interpolate(interpolationPoints, PyObject_IsTrue(periodic) ? Standard_True : Standard_False, tol3d)); } else { aBSplineInterpolation.reset(new GeomAPI_Interpolate(interpolationPoints, parameters, PyObject_IsTrue(periodic) ? Standard_True : Standard_False, tol3d)); } if (t1 && t2) { Base::Vector3d v1 = Py::Vector(t1,false).toVector(); Base::Vector3d v2 = Py::Vector(t2,false).toVector(); gp_Vec initTangent(v1.x,v1.y,v1.z), finalTangent(v2.x,v2.y,v2.z); aBSplineInterpolation->Load(initTangent, finalTangent, PyObject_IsTrue(scale) ? Standard_True : Standard_False); } else if (ts && fl) { Py::Sequence tlist(ts); TColgp_Array1OfVec tangents(1, tlist.size()); Standard_Integer index = 1; for (Py::Sequence::iterator it = tlist.begin(); it != tlist.end(); ++it) { Py::Vector v(*it); Base::Vector3d vec = v.toVector(); tangents.SetValue(index++, gp_Vec(vec.x,vec.y,vec.z)); } Py::Sequence flist(fl); Handle_TColStd_HArray1OfBoolean tangentFlags = new TColStd_HArray1OfBoolean(1, flist.size()); Standard_Integer findex = 1; for (Py::Sequence::iterator it = flist.begin(); it != flist.end(); ++it) { Py::Boolean flag(*it); tangentFlags->SetValue(findex++, static_cast<bool>(flag) ? Standard_True : Standard_False); } aBSplineInterpolation->Load(tangents, tangentFlags, PyObject_IsTrue(scale) ? Standard_True : Standard_False); } aBSplineInterpolation->Perform(); if (aBSplineInterpolation->IsDone()) { Handle_Geom_BSplineCurve aBSplineCurve(aBSplineInterpolation->Curve()); this->getGeomBSplineCurvePtr()->setHandle(aBSplineCurve); Py_Return; } else { Standard_Failure::Raise("failed to interpolate points"); return 0; // goes to the catch block } } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); std::string err = e->GetMessageString(); if (err.empty()) err = e->DynamicType()->Name(); PyErr_SetString(PartExceptionOCCError, err.c_str()); return 0; } }