diff --git a/src/Base/BoundBox.h b/src/Base/BoundBox.h index e2dff7b33..dcbfcbcaf 100644 --- a/src/Base/BoundBox.h +++ b/src/Base/BoundBox.h @@ -133,7 +133,7 @@ public: * the base \a rcVct and the direction \a rcVctDir. \a rcVct must lie inside the * bounding box. */ - Vector3<_Precision> IntersectionPoint (const Vector3<_Precision> &rcVct, const Vector3<_Precision> &rcVctDir) const; + bool IntersectionPoint (const Vector3<_Precision> &rcVct, const Vector3<_Precision> &rcVctDir, Vector3<_Precision>& cVctRes, _Precision epsilon) const; /** Checks for intersection with line incl. search tolerance. */ bool IsCutLine ( const Vector3<_Precision>& rcBase, const Vector3<_Precision>& rcDir, _Precision fTolerance = 0.0f) const; /** Checks if this plane specified by (point,normal) cuts this box. */ @@ -503,44 +503,32 @@ inline bool BoundBox3<_Precision>::CalcDistance (unsigned short usEdge, Vector3< } template -inline Vector3<_Precision> BoundBox3<_Precision>::IntersectionPoint (const Vector3<_Precision> &rcVct, const Vector3<_Precision> &rcVctDir) const +inline bool BoundBox3<_Precision>::IntersectionPoint (const Vector3<_Precision> &rcVct, const Vector3<_Precision> &rcVctDir, Vector3<_Precision>& cVctRes, _Precision epsilon) const { - BoundBox3<_Precision> cCmpBound(*this); - bool rc; - unsigned short i; - Vector3<_Precision> cVctRes; + bool rc=false; + BoundBox3<_Precision> cCmpBound(*this); + unsigned short i; - // Vergleichs-BB um REEN_EPS vergroessern - cCmpBound.MaxX += traits_type::epsilon(); - cCmpBound.MaxY += traits_type::epsilon(); - cCmpBound.MaxZ += traits_type::epsilon(); - cCmpBound.MinX -= traits_type::epsilon(); - cCmpBound.MinY -= traits_type::epsilon(); - cCmpBound.MinZ -= traits_type::epsilon(); + // enlarge bounding box by epsilon + cCmpBound.Enlarge(epsilon); - // Liegt Punkt innerhalb ? - if (cCmpBound.IsInBox (rcVct)) - { - // Seitenebenen testen - for (i = 0, rc = false; (i < 6) && (!rc); i++) - { - rc = IntersectPlaneWithLine( i, rcVct, rcVctDir, cVctRes ); - if(!cCmpBound.IsInBox(cVctRes)) - rc = false; - if (rc == true ) - { - // Liegt Schnittpunkt in gesuchter Richtung - // oder wurde gegenueberliegende Seite gefunden ? - // -> Skalarprodukt beider Richtungsvektoren > 0 (Winkel < 90) - rc = ((cVctRes - rcVct) * rcVctDir) > 0.0F; - } + // Is point inside? + if (cCmpBound.IsInBox (rcVct)) { + // test sides + for (i = 0; (i < 6) && (!rc); i++) { + rc = IntersectPlaneWithLine(i, rcVct, rcVctDir, cVctRes); + if (!cCmpBound.IsInBox(cVctRes)) + rc = false; + if (rc == true) { + // does intersection point lie in desired direction + // or was found the opposing side? + // -> scalar product of both direction vectors > 0 (angle < 90) + rc = ((cVctRes - rcVct) * rcVctDir) >= (_Precision)0.0; + } + } } - } - else - rc = false; - // Schnittpunkt zurueckgeben - return cVctRes; + return rc; } template diff --git a/src/Base/BoundBoxPy.xml b/src/Base/BoundBoxPy.xml index 4529ef5e8..afa16c55f 100644 --- a/src/Base/BoundBoxPy.xml +++ b/src/Base/BoundBoxPy.xml @@ -53,8 +53,10 @@ A negative value shrinks the box. - method Vector getIntersectionPoint(Vector Base, Vector Dir) + method Vector getIntersectionPoint(Vector Base, Vector Dir, [float epsilon=0.0001]) Calculate the intersection point of a line with the BoundBox +The Base point must lie inside the bounding box, if not an +exception is thrown. @@ -71,7 +73,15 @@ Move the BoundBox by the given vector Check if the plane specified by Base and Normal intersects (cuts) the BoundBox - + + + + method bool isInside(Vector Base|BoundBox box) +Check if the point or bounding box is inside this bounding box + + + + Center point of the bounding box diff --git a/src/Base/BoundBoxPyImp.cpp b/src/Base/BoundBoxPyImp.cpp index 24b279e55..63dc76378 100644 --- a/src/Base/BoundBoxPyImp.cpp +++ b/src/Base/BoundBoxPyImp.cpp @@ -183,16 +183,17 @@ PyObject* BoundBoxPy::enlarge(PyObject *args) PyObject* BoundBoxPy::getIntersectionPoint(PyObject *args) { PyObject *object,*object2; - if (PyArg_ParseTuple(args,"O!O!:Need base and direction vector", - &(Base::VectorPy::Type), &object,&(Base::VectorPy::Type), &object2)) { - Base::Vector3d point = getBoundBoxPtr()->IntersectionPoint( + double epsilon=0.0001; + if (PyArg_ParseTuple(args,"O!O!|d:Need base and direction vector", + &(Base::VectorPy::Type), &object,&(Base::VectorPy::Type), &object2, &epsilon)) { + Base::Vector3d point; + bool ok = getBoundBoxPtr()->IntersectionPoint( *(static_cast(object)->getVectorPtr()), - *(static_cast(object2)->getVectorPtr())); + *(static_cast(object2)->getVectorPtr()), + point, epsilon); // IsInBox() doesn't handle border points correctly BoundBoxPy::PointerType bb = getBoundBoxPtr(); - if ((bb->MinX <= point.x && bb->MaxX >= point.x) && - (bb->MinY <= point.y && bb->MaxY >= point.y) && - (bb->MinZ <= point.z && bb->MaxZ >= point.z)) { + if (ok) { return new VectorPy(point); } else { @@ -249,6 +250,29 @@ PyObject* BoundBoxPy::isCutPlane(PyObject *args) return Py::new_reference_to(retVal); } +PyObject* BoundBoxPy::isInside(PyObject *args) +{ + PyObject *object; + Py::Boolean retVal; + + if (!PyArg_ParseTuple(args,"O", &object)) + return 0; + if (PyObject_TypeCheck(object, &(Base::VectorPy::Type))) { + Base::VectorPy *vec = static_cast(object); + retVal = getBoundBoxPtr()->IsInBox(*vec->getVectorPtr()); + } + else if (PyObject_TypeCheck(object, &(Base::BoundBoxPy::Type))) { + Base::BoundBoxPy *box = static_cast(object); + retVal = getBoundBoxPtr()->IsInBox(*box->getBoundBoxPtr()); + } + else { + PyErr_SetString(PyExc_TypeError, "Either a Vector or BoundBox object expected"); + return 0; + } + + return Py::new_reference_to(retVal); +} + Py::Object BoundBoxPy::getCenter(void) const { return Py::Vector(getBoundBoxPtr()->CalcCenter());