diff --git a/src/Mod/Part/App/AppPart.cpp b/src/Mod/Part/App/AppPart.cpp
index 4e623335a..cc614c9c1 100644
--- a/src/Mod/Part/App/AppPart.cpp
+++ b/src/Mod/Part/App/AppPart.cpp
@@ -75,7 +75,6 @@
#include "ArcOfHyperbolaPy.h"
#include "BezierCurvePy.h"
#include "BSplineCurvePy.h"
-#include "HermiteCurvePy.h"
#include "HyperbolaPy.h"
#include "OffsetCurvePy.h"
#include "ParabolaPy.h"
@@ -201,7 +200,6 @@ PyMODINIT_FUNC initPart()
Base::Interpreter().addType(&Part::ArcOfHyperbolaPy ::Type,partModule,"ArcOfHyperbola");
Base::Interpreter().addType(&Part::BezierCurvePy ::Type,partModule,"BezierCurve");
Base::Interpreter().addType(&Part::BSplineCurvePy ::Type,partModule,"BSplineCurve");
- Base::Interpreter().addType(&Part::HermiteCurvePy ::Type,partModule,"HermiteCurve");
Base::Interpreter().addType(&Part::OffsetCurvePy ::Type,partModule,"OffsetCurve");
Base::Interpreter().addType(&Part::PlanePy ::Type,partModule,"Plane");
@@ -322,7 +320,6 @@ PyMODINIT_FUNC initPart()
Part::GeomCurve ::init();
Part::GeomBezierCurve ::init();
Part::GeomBSplineCurve ::init();
- Part::GeomHermiteCurve ::init();
Part::GeomCircle ::init();
Part::GeomArcOfCircle ::init();
Part::GeomArcOfEllipse ::init();
diff --git a/src/Mod/Part/App/BSplineCurvePy.xml b/src/Mod/Part/App/BSplineCurvePy.xml
index 2047f1e78..5ce664c0c 100644
--- a/src/Mod/Part/App/BSplineCurvePy.xml
+++ b/src/Mod/Part/App/BSplineCurvePy.xml
@@ -327,6 +327,11 @@ from the knots table of this B-Spline curve.
+
+
+ Compute the tangents for a Cardinal spline
+
+
diff --git a/src/Mod/Part/App/BSplineCurvePyImp.cpp b/src/Mod/Part/App/BSplineCurvePyImp.cpp
index 7bbde729b..ab16b4b9e 100644
--- a/src/Mod/Part/App/BSplineCurvePyImp.cpp
+++ b/src/Mod/Part/App/BSplineCurvePyImp.cpp
@@ -865,6 +865,66 @@ PyObject* BSplineCurvePy::approximate(PyObject *args, PyObject *kwds)
}
}
+PyObject* BSplineCurvePy::getCardinalSplineTangents(PyObject *args, PyObject *kwds)
+{
+ PyObject* pts;
+ PyObject* tgs;
+ double parameter;
+
+ static char* kwds_interp1[] = {"Points", "Parameter", NULL};
+ if (PyArg_ParseTupleAndKeywords(args, kwds, "Od",kwds_interp1, &pts, ¶meter)) {
+ Py::Sequence list(pts);
+ std::vector interpPoints;
+ interpPoints.reserve(list.size());
+ for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
+ Py::Vector v(*it);
+ Base::Vector3d pnt = v.toVector();
+ interpPoints.push_back(gp_Pnt(pnt.x,pnt.y,pnt.z));
+ }
+
+ GeomBSplineCurve* bspline = this->getGeomBSplineCurvePtr();
+ std::vector tangents;
+ bspline->getCardinalSplineTangents(interpPoints, parameter, tangents);
+
+ Py::List vec;
+ for (gp_Vec it : tangents)
+ vec.append(Py::Vector(Base::Vector3d(it.X(), it.Y(), it.Z())));
+ return Py::new_reference_to(vec);
+ }
+
+ PyErr_Clear();
+ static char* kwds_interp2[] = {"Points", "Parameters", NULL};
+ if (PyArg_ParseTupleAndKeywords(args, kwds, "OO",kwds_interp2, &pts, &tgs)) {
+ Py::Sequence list(pts);
+ std::vector interpPoints;
+ interpPoints.reserve(list.size());
+ for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
+ Py::Vector v(*it);
+ Base::Vector3d pnt = v.toVector();
+ interpPoints.push_back(gp_Pnt(pnt.x,pnt.y,pnt.z));
+ }
+
+ Py::Sequence list2(tgs);
+ std::vector parameters;
+ parameters.reserve(list2.size());
+ for (Py::Sequence::iterator it = list2.begin(); it != list2.end(); ++it) {
+ Py::Float p(*it);
+ parameters.push_back(static_cast(p));
+ }
+
+ GeomBSplineCurve* bspline = this->getGeomBSplineCurvePtr();
+ std::vector tangents;
+ bspline->getCardinalSplineTangents(interpPoints, parameters, tangents);
+
+ Py::List vec;
+ for (gp_Vec it : tangents)
+ vec.append(Py::Vector(Base::Vector3d(it.X(), it.Y(), it.Z())));
+ return Py::new_reference_to(vec);
+ }
+
+ return 0;
+}
+
PyObject* BSplineCurvePy::interpolate(PyObject *args, PyObject *kwds)
{
PyObject* obj;
diff --git a/src/Mod/Part/App/CMakeLists.txt b/src/Mod/Part/App/CMakeLists.txt
index dba514687..bee0cdcee 100644
--- a/src/Mod/Part/App/CMakeLists.txt
+++ b/src/Mod/Part/App/CMakeLists.txt
@@ -56,7 +56,6 @@ generate_from_xml(LinePy)
generate_from_xml(PointPy)
generate_from_xml(BezierCurvePy)
generate_from_xml(BSplineCurvePy)
-generate_from_xml(HermiteCurvePy)
generate_from_xml(PlanePy)
generate_from_xml(ConePy)
generate_from_xml(CylinderPy)
@@ -195,8 +194,6 @@ SET(Python_SRCS
BezierCurvePyImp.cpp
BSplineCurvePy.xml
BSplineCurvePyImp.cpp
- HermiteCurvePy.xml
- HermiteCurvePyImp.cpp
PlanePy.xml
PlanePyImp.cpp
ConePy.xml
diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp
index a9adf80f4..e3c97c853 100644
--- a/src/Mod/Part/App/Geometry.cpp
+++ b/src/Mod/Part/App/Geometry.cpp
@@ -98,33 +98,32 @@
#endif
-#include "LinePy.h"
#include
-#include "CirclePy.h"
-#include "EllipsePy.h"
-#include "ArcPy.h"
-#include "ArcOfCirclePy.h"
-#include "ArcOfEllipsePy.h"
-#include "ArcOfParabolaPy.h"
-#include "BezierCurvePy.h"
-#include "BSplineCurvePy.h"
-#include "HermiteCurvePy.h"
-#include "HyperbolaPy.h"
-#include "ArcOfHyperbolaPy.h"
-#include "OffsetCurvePy.h"
-#include "ParabolaPy.h"
-#include "BezierSurfacePy.h"
-#include "BSplineSurfacePy.h"
-#include "ConePy.h"
-#include "CylinderPy.h"
-#include "OffsetSurfacePy.h"
-#include "PlateSurfacePy.h"
-#include "PlanePy.h"
-#include "RectangularTrimmedSurfacePy.h"
-#include "SpherePy.h"
-#include "SurfaceOfExtrusionPy.h"
-#include "SurfaceOfRevolutionPy.h"
-#include "ToroidPy.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
#include
@@ -473,148 +472,6 @@ PyObject *GeomBezierCurve::getPyObject(void)
// -------------------------------------------------
-TYPESYSTEM_SOURCE(Part::GeomHermiteCurve,Part::GeomCurve);
-
-GeomHermiteCurve::GeomHermiteCurve()
-{
- std::vector p;
- p.push_back(gp_Pnt(0.0,0.0,0.0));
- p.push_back(gp_Pnt(1.0,0.0,0.0));
-
- std::vector t;
- t.push_back(gp_Vec(1,0,0));
- t.push_back(gp_Vec(1,0,0));
-
- compute(p, t);
-}
-
-GeomHermiteCurve::GeomHermiteCurve(const std::vector& p,
- const std::vector& t)
-{
- compute(p, t);
-}
-
-GeomHermiteCurve::~GeomHermiteCurve()
-{
-}
-
-void GeomHermiteCurve::interpolate(const std::vector& p,
- const std::vector& t)
-{
- if (p.size() < 2)
- Standard_ConstructionError::Raise();
- if (p.size() != t.size())
- Standard_ConstructionError::Raise();
-
- compute(p, t);
-}
-
-void GeomHermiteCurve::getCardinalSplineTangents(const std::vector& p,
- const std::vector& c,
- std::vector& t) const
-{
- // https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline#Cardinal_Spline
- if (p.size() < 2)
- Standard_ConstructionError::Raise();
- if (p.size() != c.size())
- Standard_ConstructionError::Raise();
-
- t.resize(p.size());
- if (p.size() == 2) {
- t[0] = gp_Vec(p[0], p[1]);
- t[1] = gp_Vec(p[0], p[1]);
- }
- else {
- std::size_t e = p.size() - 1;
-
- for (std::size_t i = 1; i < e; i++) {
- gp_Vec v = gp_Vec(p[i-1], p[i+1]);
- double f = 0.5 * (1-c[i]);
- v.Scale(f);
- t[i] = v;
- }
-
- t[0] = t[1];
- t[t.size()-1] = t[t.size()-2];
- }
-}
-
-void GeomHermiteCurve::getCardinalSplineTangents(const std::vector& p, double c,
- std::vector& t) const
-{
- // https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline#Cardinal_Spline
- if (p.size() < 2)
- Standard_ConstructionError::Raise();
-
- t.resize(p.size());
- if (p.size() == 2) {
- t[0] = gp_Vec(p[0], p[1]);
- t[1] = gp_Vec(p[0], p[1]);
- }
- else {
- std::size_t e = p.size() - 1;
- double f = 0.5 * (1-c);
-
- for (std::size_t i = 1; i < e; i++) {
- gp_Vec v = gp_Vec(p[i-1], p[i+1]);
- v.Scale(f);
- t[i] = v;
- }
-
- t[0] = t[1];
- t[t.size()-1] = t[t.size()-2];
- }
-}
-
-const Handle_Geom_Geometry& GeomHermiteCurve::handle() const
-{
- return myCurve;
-}
-
-void GeomHermiteCurve::compute(const std::vector& p,
- const std::vector& t)
-{
- double tol3d = Precision::Approximation();
- Handle_TColgp_HArray1OfPnt pts = new TColgp_HArray1OfPnt(1, p.size());
- for (std::size_t i=0; iSetValue(i+1, p[i]);
- }
-
- TColgp_Array1OfVec tgs(1, t.size());
- Handle_TColStd_HArray1OfBoolean fgs = new TColStd_HArray1OfBoolean(1, t.size());
- for (std::size_t i=0; iSetValue(i+1, Standard_True);
- }
-
- GeomAPI_Interpolate interpolate(pts, Standard_False, tol3d);
- interpolate.Load(tgs, fgs);
- interpolate.Perform();
- this->myCurve = interpolate.Curve();
-
- this->poles = p;
- this->tangents = t;
-}
-
-Geometry *GeomHermiteCurve::clone(void) const
-{
- GeomHermiteCurve *newCurve = new GeomHermiteCurve(poles, tangents);
- newCurve->Construction = this->Construction;
- return newCurve;
-}
-
-// Persistence implementer
-unsigned int GeomHermiteCurve::getMemSize (void) const {assert(0); return 0;/* not implemented yet */}
-void GeomHermiteCurve::Save (Base::Writer &/*writer*/) const {assert(0); /* not implemented yet */}
-void GeomHermiteCurve::Restore (Base::XMLReader &/*reader*/) {assert(0); /* not implemented yet */}
-
-PyObject *GeomHermiteCurve::getPyObject(void)
-{
- return new HermiteCurvePy(static_cast(this->clone()));
-}
-
-// -------------------------------------------------
-
TYPESYSTEM_SOURCE(Part::GeomBSplineCurve,Part::GeomCurve);
GeomBSplineCurve::GeomBSplineCurve()
@@ -703,6 +560,90 @@ bool GeomBSplineCurve::join(const Handle_Geom_BSplineCurve& spline)
return true;
}
+void GeomBSplineCurve::interpolate(const std::vector& p,
+ const std::vector& t)
+{
+ if (p.size() < 2)
+ Standard_ConstructionError::Raise();
+ if (p.size() != t.size())
+ Standard_ConstructionError::Raise();
+
+ double tol3d = Precision::Approximation();
+ Handle_TColgp_HArray1OfPnt pts = new TColgp_HArray1OfPnt(1, p.size());
+ for (std::size_t i=0; iSetValue(i+1, p[i]);
+ }
+
+ TColgp_Array1OfVec tgs(1, t.size());
+ Handle_TColStd_HArray1OfBoolean fgs = new TColStd_HArray1OfBoolean(1, t.size());
+ for (std::size_t i=0; iSetValue(i+1, Standard_True);
+ }
+
+ GeomAPI_Interpolate interpolate(pts, Standard_False, tol3d);
+ interpolate.Load(tgs, fgs);
+ interpolate.Perform();
+ this->myCurve = interpolate.Curve();
+}
+
+void GeomBSplineCurve::getCardinalSplineTangents(const std::vector& p,
+ const std::vector& c,
+ std::vector& t) const
+{
+ // https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline#Cardinal_Spline
+ if (p.size() < 2)
+ Standard_ConstructionError::Raise();
+ if (p.size() != c.size())
+ Standard_ConstructionError::Raise();
+
+ t.resize(p.size());
+ if (p.size() == 2) {
+ t[0] = gp_Vec(p[0], p[1]);
+ t[1] = gp_Vec(p[0], p[1]);
+ }
+ else {
+ std::size_t e = p.size() - 1;
+
+ for (std::size_t i = 1; i < e; i++) {
+ gp_Vec v = gp_Vec(p[i-1], p[i+1]);
+ double f = 0.5 * (1-c[i]);
+ v.Scale(f);
+ t[i] = v;
+ }
+
+ t[0] = t[1];
+ t[t.size()-1] = t[t.size()-2];
+ }
+}
+
+void GeomBSplineCurve::getCardinalSplineTangents(const std::vector& p, double c,
+ std::vector& t) const
+{
+ // https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline#Cardinal_Spline
+ if (p.size() < 2)
+ Standard_ConstructionError::Raise();
+
+ t.resize(p.size());
+ if (p.size() == 2) {
+ t[0] = gp_Vec(p[0], p[1]);
+ t[1] = gp_Vec(p[0], p[1]);
+ }
+ else {
+ std::size_t e = p.size() - 1;
+ double f = 0.5 * (1-c);
+
+ for (std::size_t i = 1; i < e; i++) {
+ gp_Vec v = gp_Vec(p[i-1], p[i+1]);
+ v.Scale(f);
+ t[i] = v;
+ }
+
+ t[0] = t[1];
+ t[t.size()-1] = t[t.size()-2];
+ }
+}
+
void GeomBSplineCurve::makeC1Continuous(double tol, double ang_tol)
{
GeomConvert::C0BSplineToC1BSplineCurve(this->myCurve, tol, ang_tol);
diff --git a/src/Mod/Part/App/Geometry.h b/src/Mod/Part/App/Geometry.h
index 464cfa41e..0453316ca 100644
--- a/src/Mod/Part/App/Geometry.h
+++ b/src/Mod/Part/App/Geometry.h
@@ -153,20 +153,15 @@ private:
Handle_Geom_BezierCurve myCurve;
};
-/*!
- * \brief The GeomHermiteCurve class
- * The GeomHermiteCurve describes a cubic Hermite spline.
- * @note Since OpenCascade doesn't directly support Hermite splines
- * the returned curve will be a B-Spline curve.
- */
-class PartExport GeomHermiteCurve : public GeomCurve
+class PartExport GeomBSplineCurve : public GeomCurve
{
TYPESYSTEM_HEADER();
public:
- GeomHermiteCurve();
- GeomHermiteCurve(const std::vector&, const std::vector&);
- virtual ~GeomHermiteCurve();
+ GeomBSplineCurve();
+ GeomBSplineCurve(const Handle_Geom_BSplineCurve&);
+ virtual ~GeomBSplineCurve();
virtual Geometry *clone(void) const;
+
/*!
* Set the poles and tangents for the cubic Hermite spline
*/
@@ -186,33 +181,6 @@ public:
void getCardinalSplineTangents(const std::vector&, double,
std::vector&) const;
- // Persistence implementer ---------------------
- virtual unsigned int getMemSize (void) const;
- virtual void Save (Base::Writer &/*writer*/) const;
- virtual void Restore(Base::XMLReader &/*reader*/);
- // Base implementer ----------------------------
- virtual PyObject *getPyObject(void);
-
- const Handle_Geom_Geometry& handle() const;
-
-private:
- void compute(const std::vector&, const std::vector&);
-
-private:
- Handle_Geom_BSplineCurve myCurve;
- std::vector poles;
- std::vector tangents;
-};
-
-class PartExport GeomBSplineCurve : public GeomCurve
-{
- TYPESYSTEM_HEADER();
-public:
- GeomBSplineCurve();
- GeomBSplineCurve(const Handle_Geom_BSplineCurve&);
- virtual ~GeomBSplineCurve();
- virtual Geometry *clone(void) const;
-
int countPoles() const;
void setPole(int index, const Base::Vector3d&, double weight=-1);
std::vector getPoles() const;
diff --git a/src/Mod/Part/App/HermiteCurvePy.xml b/src/Mod/Part/App/HermiteCurvePy.xml
deleted file mode 100644
index b35270dac..000000000
--- a/src/Mod/Part/App/HermiteCurvePy.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
- Describes a Hermite curve
-
-
-
-
- Set the poles and tangents to compute the Hermite curve.
-
-
-
-
- Compute the tangents for a Cardinal spline
-
-
-
-
diff --git a/src/Mod/Part/App/HermiteCurvePyImp.cpp b/src/Mod/Part/App/HermiteCurvePyImp.cpp
deleted file mode 100644
index b87826fc2..000000000
--- a/src/Mod/Part/App/HermiteCurvePyImp.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2016 Werner Mayer *
- * *
- * This file is part of the FreeCAD CAx development system. *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Library General Public *
- * License as published by the Free Software Foundation; either *
- * version 2 of the License, or (at your option) any later version. *
- * *
- * This library is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU Library General Public License for more details. *
- * *
- * You should have received a copy of the GNU Library General Public *
- * License along with this library; see the file COPYING.LIB. If not, *
- * write to the Free Software Foundation, Inc., 59 Temple Place, *
- * Suite 330, Boston, MA 02111-1307, USA *
- * *
- ***************************************************************************/
-
-
-#include "PreCompiled.h"
-
-#include "Geometry.h"
-#include
-
-#include
-#include
-#include
-
-using namespace Part;
-
-// returns a string which represents the object e.g. when printed in python
-std::string HermiteCurvePy::representation(void) const
-{
- return std::string("");
-}
-
-PyObject *HermiteCurvePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
-{
- // create a new instance of HermiteCurvePy and the Twin object
- return new HermiteCurvePy(new GeomHermiteCurve);
-}
-
-// constructor method
-int HermiteCurvePy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
-{
- return 0;
-}
-
-PyObject* HermiteCurvePy::interpolate(PyObject *args, PyObject *kwds)
-{
- PyObject* pts;
- PyObject* tgs;
-
- static char* kwds_interp1[] = {"Points", "Tangents", NULL};
- if (PyArg_ParseTupleAndKeywords(args, kwds, "OO",kwds_interp1, &pts, &tgs)) {
- Py::Sequence list(pts);
- std::vector interpPoints;
- interpPoints.reserve(list.size());
- for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
- Py::Vector v(*it);
- Base::Vector3d pnt = v.toVector();
- interpPoints.push_back(gp_Pnt(pnt.x,pnt.y,pnt.z));
- }
- Py::Sequence list2(tgs);
- std::vector interpTangents;
- interpTangents.reserve(list2.size());
- for (Py::Sequence::iterator it = list2.begin(); it != list2.end(); ++it) {
- Py::Vector v(*it);
- Base::Vector3d vec = v.toVector();
- interpTangents.push_back(gp_Vec(vec.x,vec.y,vec.z));
- }
-
- GeomHermiteCurve* hermite = this->getGeomHermiteCurvePtr();
- hermite->interpolate(interpPoints, interpTangents);
- Handle_Geom_BSplineCurve aBSpline = Handle_Geom_BSplineCurve::DownCast
- (hermite->handle());
- return new BSplineCurvePy(new GeomBSplineCurve(aBSpline));
- }
-
- return 0;
-}
-
-PyObject* HermiteCurvePy::getCardinalSplineTangents(PyObject *args, PyObject *kwds)
-{
- PyObject* pts;
- PyObject* tgs;
- double parameter;
-
- static char* kwds_interp1[] = {"Points", "Parameter", NULL};
- if (PyArg_ParseTupleAndKeywords(args, kwds, "Od",kwds_interp1, &pts, ¶meter)) {
- Py::Sequence list(pts);
- std::vector interpPoints;
- interpPoints.reserve(list.size());
- for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
- Py::Vector v(*it);
- Base::Vector3d pnt = v.toVector();
- interpPoints.push_back(gp_Pnt(pnt.x,pnt.y,pnt.z));
- }
-
- GeomHermiteCurve* hermite = this->getGeomHermiteCurvePtr();
- std::vector tangents;
- hermite->getCardinalSplineTangents(interpPoints, parameter, tangents);
-
- Py::List vec;
- for (gp_Vec it : tangents)
- vec.append(Py::Vector(Base::Vector3d(it.X(), it.Y(), it.Z())));
- return Py::new_reference_to(vec);
- }
-
- PyErr_Clear();
- static char* kwds_interp2[] = {"Points", "Parameters", NULL};
- if (PyArg_ParseTupleAndKeywords(args, kwds, "OO",kwds_interp2, &pts, &tgs)) {
- Py::Sequence list(pts);
- std::vector interpPoints;
- interpPoints.reserve(list.size());
- for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
- Py::Vector v(*it);
- Base::Vector3d pnt = v.toVector();
- interpPoints.push_back(gp_Pnt(pnt.x,pnt.y,pnt.z));
- }
-
- Py::Sequence list2(tgs);
- std::vector parameters;
- parameters.reserve(list2.size());
- for (Py::Sequence::iterator it = list2.begin(); it != list2.end(); ++it) {
- Py::Float p(*it);
- parameters.push_back(static_cast(p));
- }
-
- GeomHermiteCurve* hermite = this->getGeomHermiteCurvePtr();
- std::vector tangents;
- hermite->getCardinalSplineTangents(interpPoints, parameters, tangents);
-
- Py::List vec;
- for (gp_Vec it : tangents)
- vec.append(Py::Vector(Base::Vector3d(it.X(), it.Y(), it.Z())));
- return Py::new_reference_to(vec);
- }
-
- return 0;
-}
-
-PyObject *HermiteCurvePy::getCustomAttributes(const char* /*attr*/) const
-{
- return 0;
-}
-
-int HermiteCurvePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
-{
- return 0;
-}