/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2019, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2019 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #include "OdaCommon.h" #include "ExDbCurveIntersectionPE.h" #include "DbCurve.h" #include "Ge/GeLineSeg3d.h" #include "Ge/GeCircArc3d.h" #include "Ge/GeEllipArc3d.h" OdResult ExDbCurveIntersectionPE::intersectWith( const OdDbEntity* pThisEnt, const OdDbEntity* pEnt, OdDb::Intersect intType, OdGePoint3dArray& points, OdGsMarker thisGsMarker, OdGsMarker otherGsMarker) const { OdDbCurvePtr pEnt1 = pThisEnt; if (thisGsMarker) { pEnt1 = pThisEnt->subentPtr(OdDbFullSubentPath(OdDb::kEdgeSubentType, thisGsMarker)); } if (pEnt1.isNull()) return eDegenerateGeometry; OdDbCurvePtr pEnt2 = pEnt; if (otherGsMarker) { pEnt2 = pEnt->subentPtr(OdDbFullSubentPath(OdDb::kEdgeSubentType, otherGsMarker)); } if (pEnt2.isNull()) return eDegenerateGeometry; OdGeCurve3d* pGeCurve1 = NULL; OdResult res = pEnt1->getOdGeCurve(pGeCurve1); if (res != eOk) return res; OdGeCurve3d* pGeCurve2 = NULL; res = pEnt2->getOdGeCurve(pGeCurve2); if (res != eOk) { delete pGeCurve1; delete pGeCurve2; return res; } int nIntersections = 0; OdGePoint3d pt1, pt2; switch (pGeCurve1->type()) { case OdGe::kLineSeg3d: { OdGeLineSeg3d* pLineSeg1 = (OdGeLineSeg3d*)pGeCurve1; OdGeLine3d Line1; if ( OdDb::kExtendThis == intType || OdDb::kExtendBoth == intType) { pLineSeg1->getLine( Line1 ); } switch (pGeCurve2->type()) { case OdGe::kLineSeg3d: { OdGeLinearEnt3d* pLineSeg2 = (OdGeLinearEnt3d*)pGeCurve2; switch (intType) { case OdDb::kOnBothOperands: if (pLineSeg2->intersectWith( *pLineSeg1, pt1)) ++nIntersections; break; case OdDb::kExtendThis: if (pLineSeg2->intersectWith( Line1, pt1)) ++nIntersections; break; case OdDb::kExtendArg: { OdGeLine3d Line2; pLineSeg2->getLine( Line2 ); if (Line2.intersectWith(*pLineSeg1, pt1)) ++nIntersections; } break; case OdDb::kExtendBoth: { OdGeLine3d Line2; pLineSeg2->getLine( Line2 ); if (Line2.intersectWith(Line1, pt1)) ++nIntersections; } break; } } break; case OdGe::kCircArc3d: { OdGeCircArc3d* pArc = (OdGeCircArc3d*)pGeCurve2; if ( OdDb::kExtendArg == intType || OdDb::kExtendBoth == intType) { pArc->setAngles( 0, Oda2PI ); } if ( OdDb::kExtendThis == intType || OdDb::kExtendBoth == intType) { pArc->intersectWith(Line1, nIntersections, pt1, pt2); } else { pArc->intersectWith(*pLineSeg1, nIntersections, pt1, pt2); } } break; case OdGe::kEllipArc3d: { OdGeEllipArc3d* pArc = (OdGeEllipArc3d*)pGeCurve2; if ( OdDb::kExtendArg == intType || OdDb::kExtendBoth == intType) { pArc->setAngles( 0, Oda2PI ); } if ( OdDb::kExtendThis == intType || OdDb::kExtendBoth == intType) { pArc->intersectWith(Line1, nIntersections, pt1, pt2); } else { pArc->intersectWith(*pLineSeg1, nIntersections, pt1, pt2); } } break; default: res = eNotImplementedYet; } } break; case OdGe::kCircArc3d: { OdGeCircArc3d* pArc = (OdGeCircArc3d*)pGeCurve1; if ( OdDb::kExtendThis == intType || OdDb::kExtendBoth == intType) { pArc->setAngles( 0, Oda2PI ); } switch (pGeCurve2->type()) { case OdGe::kLineSeg3d: { OdGeLinearEnt3d* pLine = (OdGeLinearEnt3d*)pGeCurve2; OdGeLine3d Line2; if ( OdDb::kExtendArg == intType || OdDb::kExtendBoth == intType) { pLine->getLine( Line2 ); pArc->intersectWith( Line2, nIntersections, pt1, pt2); } else { pArc->intersectWith( *pLine, nIntersections, pt1, pt2); } } break; case OdGe::kCircArc3d: { OdGeCircArc3d* pArc2 = (OdGeCircArc3d*)pGeCurve2; if ( OdDb::kExtendArg == intType || OdDb::kExtendBoth == intType) { pArc2->setAngles( 0, Oda2PI ); } pArc->intersectWith(*pArc2, nIntersections, pt1, pt2); } break; default: res = eNotImplementedYet; } } // CircArc3d break; case OdGe::kEllipArc3d: { OdGeEllipArc3d* pArc = (OdGeEllipArc3d*)pGeCurve1; if ( OdDb::kExtendThis == intType || OdDb::kExtendBoth == intType) { pArc->setAngles( 0, Oda2PI ); } switch (pGeCurve2->type()) { case OdGe::kLineSeg3d: { OdGeLinearEnt3d* pLine = (OdGeLinearEnt3d*)pGeCurve2; OdGeLine3d Line2; if ( OdDb::kExtendArg == intType || OdDb::kExtendBoth == intType) { pLine->getLine( Line2 ); pArc->intersectWith( Line2, nIntersections, pt1, pt2); } else { pArc->intersectWith(*pLine, nIntersections, pt1, pt2); } } break; default: res = eNotImplementedYet; } } break; // kEllipArc3d default: res = eNotImplementedYet; } if (res == eNotImplementedYet) { // Intersect polylines OdGePoint3dArray arrPt1, arrPt2; pGeCurve1->getSamplePoints(NULL, OdGeContext::gTol.equalPoint(), arrPt1); if (arrPt1.size() < 2) { delete pGeCurve1; delete pGeCurve2; return eDegenerateGeometry; } pGeCurve2->getSamplePoints(NULL, OdGeContext::gTol.equalPoint(), arrPt2); if (arrPt2.size() < 2) { delete pGeCurve1; delete pGeCurve2; return eDegenerateGeometry; } OdGeLineSeg3d seg1, seg2; OdGePoint3d ptInt; OdGeExtents3d ext1, ext2, extCurve2; const OdGePoint3d* pPt1 = arrPt1.asArrayPtr(); for (int i = arrPt1.size() - 1; i > 0; --i) { ext1.comparingSet(*pPt1, *(pPt1 + 1)); seg1.set(*pPt1, *(pPt1 + 1)); ++pPt1; const OdGePoint3d* pPt2 = arrPt2.asArrayPtr(); int nPrevPointsSize = points.size(); for (int j = arrPt2.size() - 1; j > 0; --j) { ext2.comparingSet(*pPt2, *(pPt2 + 1)); ++pPt2; if (!ext1.isDisjoint(ext2)) { seg2.set(*(pPt2 - 1), *pPt2); if (seg1.intersectWith(seg2, ptInt)) { // Intersection point of last segment may coincide with intersection point of first // segment for closed curve if (points.size() == nPrevPointsSize // First point in this loop || j != 1 // Not last segemnt - skip check || ptInt != points[nPrevPointsSize]) // Check for last segemnt { points.append(ptInt); } } } } } // Check in case outer loop curve is closed if (points.size() > 1 && points.first() == points.last()) { points.removeLast(); } } // TODO - Check intersection type and params switch (nIntersections) { case 2: points.append(pt2); //No break case 1: points.append(pt1); break; } delete pGeCurve1; delete pGeCurve2; return eOk; } OdResult ExDbCurveIntersectionPE::intersectWith( const OdDbEntity* pThisEnt, const OdDbEntity* pEnt, OdDb::Intersect intType, const OdGePlane& projPlane, OdGePoint3dArray& points, OdGsMarker thisGsMarker, OdGsMarker otherGsMarker) const { return eNotImplementedYet; } OdResult ExDbCurveIntersectionPE::boundingBoxIntersectWith( const OdDbEntity* pThisEnt, const OdDbEntity* pEnt, OdDb::Intersect intType, OdGePoint3dArray& points, OdGsMarker thisGsMarker, OdGsMarker otherGsMarker) const { return eNotImplementedYet; } OdResult ExDbCurveIntersectionPE::boundingBoxIntersectWith( const OdDbEntity* pThisEnt, const OdDbEntity* pEnt, OdDb::Intersect intType, const OdGePlane& projPlane, OdGePoint3dArray& points, OdGsMarker thisGsMarker, OdGsMarker otherGsMarker) const { return eNotImplementedYet; }