23#ifndef __FM_T_CONTOUR2D_IMPL_H__
24#define __FM_T_CONTOUR2D_IMPL_H__
50 bool & bValidRegion );
53 std::vector< Intersection > & vecPoints,
const OdGeTol & gTol );
66template <
class TContourData >
69 protected TContourData
96 return this->_implClass();
105 return this->_closed();
113 if ( this->_closed() != bClosed )
114 this->_setClosed( bClosed );
126 return this->_empty();
132 return this->_numVerts();
139 return this->_numSegments();
168 double & dBulge )
const;
327 virtual bool areEqualParams(
double dParam1,
double dParam2,
const double dTol = 1e-10 )
const;
398 std::vector< Intersection > & vecPoints,
405 std::vector< Intersection > & vecPoints,
415 std::vector< Intersection > & vecPoints,
500 OdUInt32& iNumPeriodsAB,
const double dParamTol = DBL_EPSILON )
const;
521template <
class TContourData >
524 if (
this == &rSrcCont )
530 this->_reset( iNumVerts, bClosed );
534 for (
OdUInt32 iVert = 0; iVert < iNumVerts; iVert++ )
539 eRes = rSrcCont.
getVertexAt( iVert, & rVert.point(), & rVert.bulge(), & rVert.attributes() );
544 this->_setModifiedAll();
548template <
class TContourData >
556template <
class TContourData >
559 OdUInt32 uNumVerts = this->_numVerts();
564 if ( ! this->_vertex( 0 ).point().isEqualTo( this->_vertex( uNumVerts - 1 ).point(), gTol ) )
567 this->_removeVertices( uNumVerts - 1 );
568 this->_setClosed(
true );
574template <
class TContourData >
577 OdUInt32 iNumSeg = this->_numSegments();
580 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
582 this->_getSegment( iSeg, ImplSeg );
583 if ( ImplSeg.type() ==
estArc )
593template <
class TContourData >
597 if (
isError( this->_getSegment( iIndex, Seg ) ) )
604template <
class TContourData >
607 if ( iIndex < this->_numVerts() )
608 return this->_vertex( iIndex ).attributes();
613template <
class TContourData >
616 if ( iIndex < this->_numVerts() )
617 return this->_vertex( iIndex ).attributes();
622template <
class TContourData >
625 if ( iIndex < this->_numVerts() )
627 this->_vertex( iIndex ).attributes() = rAttr;
634template <
class TContourData >
639 if ( iIndex < this->_numVerts() )
640 uData = this->_vertex( iIndex ).attributes().metadata();
645template <
class TContourData >
650 if ( iIndex < this->_numVerts() )
651 this->_vertex( iIndex ).attributes().metadata() = uNewData;
682template <
class TContourData >
686 Result eRes = this->_getSegment( iIndex, ImplSeg );
695template <
class TContourData >
699 double & dBulge )
const
702 Result eRes = this->_getSegment( iIndex, ImplSeg );
706 ptStart = ImplSeg._startPt();
707 ptEnd = ImplSeg._endPt();
708 dBulge = ImplSeg._bulge();
716template <
class TContourData >
720 Result eRes = this->_getSegment( iIndex, ImplSeg );
724 return worstResult( eRes, ImplSeg.getLineSeg( geLine ) );
729template <
class TContourData >
733 Result eRes = this->_getSegment( iIndex, ImplSeg );
737 return worstResult( eRes, ImplSeg.getArcSeg( geArc ) );
742template <
class TContourData >
745 Result eRes = this->_normalizeIndex( iIndex );
749 ptPoint = this->_vertex(iIndex).point();
755template <
class TContourData >
758 Result eRes = this->_normalizeIndex( iIndex );
762 dBulge = this->_vertex(iIndex).bulge();
767template <
class TContourData >
770 Result eRes = this->_normalizeIndex( iIndex );
777 *pptPoint = rVert.point();
780 *pdBulge = rVert.bulge();
783 *pAttr = rVert.attributes();
789template <
class TContourData >
792 Result eRes = this->_normalizeIndex( iIndex );
796 OdUInt32 iSize = this->numSegments();
797 if( !this->_closed() && ( iIndex == 0 || iIndex == iSize-1 ) )
807 this->_getSegment( iIndex, rSeg );
808 rSeg.getTangent( 0.0, vA );
811 this->_getSegment( iSize-1, rSeg );
813 this->_getSegment( iIndex-1, rSeg );
815 rSeg.getTangent( 1.0, vB );
826template <
class TContourData >
834template <
class TContourData >
837 this->_reserveVertices( iReservedSize );
842template <
class TContourData >
845 Result eRes = this->_normalizeIndex( iIndex );
849 this->_vertex( iIndex ).point() = ptPoint;
850 this->_setModifiedVerts( iIndex );
857template <
class TContourData >
860 Result eRes = this->_normalizeIndex( iIndex );
864 this->_vertex( iIndex ).bulge() = dBulge;
865 this->_setModifiedSegs( iIndex );
871template <
class TContourData >
874 Result eRes = this->_normalizeIndex( iIndex );
879 rVert.point() = ptPoint;
880 rVert.bulge() = dBulge;
881 this->_setModifiedVerts( iIndex );
888template <
class TContourData >
891 return this->_insertVerticesAt( iIndex, 1, &ptStart, &dBulge, &rAttr );
896template <
class TContourData >
899 return this->_insertVerticesAt( this->_numVerts(), 1, &ptStart, &dBulge, &rAttr );
906template <
class TContourData >
909 if ( vecSource.
empty() )
912 return this->_insertVerticesAt( this->_numVerts(), vecSource.
size(), &(vecSource[0]) );
915template <
class TContourData >
921 return this->_insertVerticesAt( this->_numVerts(),
size, vecSource, bulgeSource );
925template <
class TContourData >
928 if ( this->_empty() )
931 double vBulges[2] = { rSeg.
bulge(), 0.0 };
933 Result eRes = this->_insertVerticesAt( 0, 2, vPoints, vBulges );
935 this->_vertex( 0 ).attributes() = rSeg.
attributes();
941 OdUInt32 iLastVert = this->_numVerts() - 1;
943 TVertexData & rLastVert = this->_vertex( iLastVert );
951 if ( !ptEnd.
isEqualTo( rSegStart, gTol ) )
959 ptSegEnd.
x += ptEnd.
x - rSegStart.
x;
960 ptSegEnd.
y += ptEnd.
y - rSegStart.
y;
963 double dBulge = rSeg.
bulge();
964 if ( dBulge != rLastVert.bulge() )
966 rLastVert.bulge() = dBulge;
967 this->_setModifiedVerts( iLastVert );
971 eRes =
worstResult( eRes, this->_insertVerticesAt( iLastVert+1, 1, &ptSegEnd ) );
978template <
class TContourData >
981 if ( this->_empty() )
985 OdUInt32 iLastVert = this->_numVerts() - 1;
986 TVertexData & rLastVert = this->_vertex( iLastVert );
989 if ( dBulge != rLastVert.bulge() )
991 rLastVert.bulge() = dBulge;
992 this->_setModifiedVerts( iLastVert );
996 rLastVert.attributes() = rAttr;
999 return this->_insertVerticesAt( iLastVert+1, 1, &ptNewEnd );
1003template <
class TContourData >
1007 if ( _isEqualToThis( rCont ) )
1013 if ( this->_empty() )
1027 OdUInt32 iLastVert = this->_numVerts() - 1;
1029 TVertexData & rLastVert = this->_vertex( iLastVert );
1034 if ( !bCloseGap || dMaxGap < ptEnd.
distanceTo( ptContStart ) )
1041 if ( rLastVert.bulge() != 0.0 )
1043 rLastVert.bulge() = 0.0;
1044 this->_setModifiedVerts( iLastVert );
1053 OdUInt32 iModifiedVert = iLastVert;
1054 this->_resize( iLastVert + iNumContVerts );
1056 for (
OdUInt32 iContVert = 0 ; iContVert < iNumContVerts; ++iContVert, ++iLastVert )
1060 eRes = rCont.
getVertexAt( iContVert, & rVert.point(), & rVert.bulge(), & rVert.attributes() );
1064 this->_setModifiedVerts( iModifiedVert, iNumContVerts );
1073template <
class TContourData >
1076 return this->_removeVertices( iIndex );
1082template <
class TContourData >
1085 if ( this->_empty() )
1088 ptPoint = this->_vertex(0).point();
1095template <
class TContourData >
1098 if ( this->_empty() )
1101 OdUInt32 iIndex = this->_closed() ? 0 : (this->_numVerts()-1);
1103 ptPoint = this->_vertex(iIndex).point();
1111template <
class TContourData >
1114 OdUInt32 iNumSeg = this->_numSegments();
1119 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1121 this->_getSegment( iSeg, ImplSeg );
1122 dL += ImplSeg.length();
1132template <
class TContourData >
1135 long iNumSegs = this->_numSegments();
1136 if ( iNumSegs <= 0 )
1143 const double dParamTol = 4*DBL_EPSILON;
1146 double dNormalizedParam = ::modf( dParam, &dIdx );
1147 long iNormalizedIdx = long( ::floor( dIdx + 0.5 ) );
1148 if ( dNormalizedParam < 0 )
1150 dNormalizedParam += 1;
1151 iNormalizedIdx -= 1;
1156 if ( iNormalizedIdx >=
long(iNumSegs) )
1158 if ( iNormalizedIdx==iNumSegs && dNormalizedParam <= dParamTol )
1161 dNormalizedParam = 1.0;
1163 else if ( this->_closed() )
1165 iNormalizedIdx = ::ldiv( iNormalizedIdx, iNumSegs ).rem;
1171 else if ( iNormalizedIdx < 0 )
1173 if ( iNormalizedIdx== -1 && dNormalizedParam >= (1.0-dParamTol) )
1176 dNormalizedParam = 0.0;
1178 else if ( this->_closed() )
1180 iNormalizedIdx = ::ldiv( iNormalizedIdx, iNumSegs ).rem + iNumSegs;
1187 dSegParam = dNormalizedParam;
1188 iIndex =
OdUInt32( iNormalizedIdx );
1190 FMGE_ASSERT( dSegParam >= -DBL_EPSILON && dSegParam <= (1.0+DBL_EPSILON) );
1198template <
class TContourData >
1204 OdUInt32 iNumSegs = this->_numSegments();
1205 if ( iNumSegs <= 0 )
1210 bool bClosed = this->_closed();
1212 bool bDistNormalized =
false;
1219 double dLength = ((
IContour2D*)
this)->length();
1220 if ( dLength <= dTol )
1224 bDistNormalized =
true;
1225 dDist -= ::floor( dDist/dLength ) * dLength;
1226 if (dDist < 0.0 || dDist >= dLength )
1232 double dCurDist = 0;
1238 this->_getSegment( iSeg, ImplSeg );
1239 double dL = ImplSeg.length();
1240 if ( (dCurDist + dL) > dDist )
1244 dSegParam = (dDist - dCurDist)/dL;
1250 }
while ( ++iSeg < iNumSegs );
1253 if ( bDistNormalized )
1255 FMGE_FAULT(
"It seems that contour::length() returned a wrong value!" );
1260 double dLength = dCurDist;
1262 if ( !this->_closed() || dLength <= dTol )
1264 iIndex = iNumSegs - 1;
1270 bDistNormalized =
true;
1271 dDist -= ::floor( dDist/dLength ) * dLength;
1272 if (dDist < 0.0 || dDist >= dLength )
1280template <
class TContourData >
1285 Result eRes = _param2IdxParam( dParam, iIndex, dSegParam );
1294 if ( dSegParam!= 0.0 )
1296 this->_getSegment( iIndex, ImplSeg );
1297 dSumLen += ImplSeg.length()*dSegParam;
1301 for (
OdUInt32 iSeg = 0; iSeg<iIndex; iSeg++ )
1303 this->_getSegment( iSeg, ImplSeg );
1304 dSumLen += ImplSeg.length();
1313template <
class TContourData >
1320 Result eRes = _param2IdxParam( dParam, iIndex, dSegParam );
1329 return worstResult( eRes, ImplSeg.getTangent( dSegParam, vTangent ) );
1335template <
class TContourData >
1339 if ( this->_numVerts()<=1 )
1341 if ( !this->_empty() &&
OdZero(dParam) )
1343 ptPoint = this->_vertex(0).point();
1354 Result eRes = _param2IdxParam( dParam, iIndex, dSegParam );
1363 return worstResult( eRes, ImplSeg.getPoint( dSegParam, ptPoint ) );
1369template <
class TContourData >
1375 if ( this->_numVerts() <= 1 )
1379 ptPoint = this->_vertex(0).point();
1390 OdUInt32 iNumSegs = this->_numSegments();
1391 if ( dParam < 0.0 || dParam > iNumSegs )
1393 FMGE_FAULT(
"Contour::getParamAtDist returned an invalid parameter value." );
1398 if ( iIndex == iNumSegs )
1402 eRes =
worstResult( eRes, this->_getSegment( iIndex, ImplSeg ) );
1406 return worstResult( eRes, ImplSeg.getPoint( dParam - iIndex, ptPoint ) );
1412template <
class TContourData >
1415 return _param2dist( dParam, dDist );
1420template <
class TContourData >
1426 Result eRes = _dist2IdxParam( dDist, iIndex, dSegParam );
1433 dParam = iIndex + dSegParam;
1442template <
class TContourData >
1445 const double dParamEps = 1e-10;
1447 int iNumSegs = this->_numSegments();
1448 if ( iNumSegs <= 0 )
1450 if ( this->_empty() )
1453 if ( ::fabs( dParam ) > dParamEps )
1463 if ( this->_closed() )
1465 if ( dParam < 0.0 || dParam >= iNumSegs )
1467 dParam -= ::floor(dParam/iNumSegs)*iNumSegs;
1468 if ( dParam < 0.0 || dParam >=iNumSegs )
1477 if ( dParam >= -dParamEps )
1482 else if ( dParam > iNumSegs )
1485 if ( dParam < (iNumSegs+dParamEps) )
1496template <
class TContourData >
1499 return _normalizeParam( dParam );
1504template <
class TContourData >
1509 double dLength =
length();
1513 if ( this->_closed() )
1515 if ( dDist < 0.0 || dDist >= dLength )
1517 if ( dLength > dTol )
1519 dDist -= ::floor(dDist/dLength)*dLength;
1520 if ( dDist < 0.0 || dDist > dLength )
1532 if ( dDist >= -dTol )
1537 else if ( dDist > dLength )
1540 if ( dDist < (dLength + dTol) )
1551template <
class TContourData >
1554 double dDelta = ::fabs( dParam2 - dParam1 );
1556 if ( this->_closed() )
1558 OdUInt32 iNumSegs = this->_numSegments();
1562 if ( dDelta > iNumSegs )
1563 dDelta -= ::floor(dDelta/iNumSegs)*iNumSegs;
1565 if ( 2.0*dDelta > iNumSegs )
1566 dDelta = iNumSegs - dDelta;
1570 return ( dDelta <= dTol );
1574template <
class TContourData >
1577 double dDelta = ::fabs( dDist2 - dDist1 );
1579 if ( this->_closed() )
1581 if ( dDelta <= dTol )
1584 double dLength =
length();
1586 if ( dLength > dTol )
1588 if ( dDelta > dLength )
1589 dDelta -= ::floor(dDelta/dLength)*dLength;
1591 if ( 2.0*dDelta > dLength )
1592 dDelta = dLength - dDelta;
1596 return ( dDelta <= dTol );
1600template <
class TContourData >
1603 if ( ! this->_closed() )
1606 return dDist2 - dDist1;
1613 if (
OdEqual( dDist1, dDist2, dTol ) )
1616 double dLength =
length();
1618 if ( dLength < dTol )
1621 if ( dDist1 < 0.0 || dDist1 >= dLength )
1622 dDist1 -= ::floor(dDist1/dLength)*dLength;
1624 if ( dDist2 < 0.0 || dDist2 >= dLength )
1625 dDist2 -= ::floor(dDist2/dLength)*dLength;
1627 bool bSwap = ( dDist1 > dDist2 );
1629 std::swap( dDist1, dDist2 );
1631 double dDelta = dDist2 - dDist1;
1633 if ( dDelta > dLength/2 )
1634 dDelta = dLength - dDelta;
1636 return bSwap ? -dDelta : dDelta;
1640template <
class TContourData >
1643 if ( dParam1 == dParam2 )
1646 double dDist1, dDist2;
1648 getDistAtParam ( dParam1, dDist1 ),
1649 getDistAtParam ( dParam2, dDist2 ) );
1653 return signedMinDist( dDist1, dDist2 );
1667template <
class TContourData >
1670 if ( this->_empty() )
1675 OdUInt32 iNumSeg = this->_numSegments();
1681 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1683 this->_getSegment( iSeg, ImplSeg );
1684 ImplSeg.addExtents( myExts );
1689 myExts.
addPoint( this->_vertex(0).point() );
1694 geExtents.
addExt( myExts );
1702template <
class TContourData >
1708 OdUInt32 iNumSeg = this->_numSegments();
1714 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1716 this->_getSegment( iSeg, ImplSeg );
1717 dSum += ImplSeg.integrate();
1720 if ( !this->_closed() )
1723 dSum +=
BulgeSeg2D( this->_vertex(iNumSeg).point(), this->_vertex(0).point() ).
integrate();
1733template <
class TContourData >
1736 bool bResult =
false;
1738 OdUInt32 iSize = this->numSegments();
1739 if( iSize > 1 && this->_closed() )
1742 this->_getSegment( iSize-1, rSeg );
1746 rSeg.getTangent( 1.0, vB );
1748 double dCrossProduct;
1752 for(
OdUInt32 i = 0; i < iSize; i++ )
1755 this->_getSegment( i, rSeg );
1756 rSeg.getTangent( 0.0, vA );
1788template <
class TContourData >
1796template <
class TContourData >
1802 OdUInt32 iNumSeg = this->_numSegments();
1808 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1810 this->_getSegment( iSeg, ImplSeg );
1813 bOn = ImplSeg.isOn( ptTest, &dSegParam, gTol );
1816 dParam = iSeg + dSegParam;
1821 else if ( !this->_empty() )
1824 bOn =
BulgeSeg2D( this->_vertex(0).point(), this->_vertex(0).point() ).
isOn( ptTest, &dParam, gTol);
1835template <
class TContourData >
1838 if ( this->_empty() )
1841 *pptNearest = ptTest;
1846 double dNearestParam = 0;
1850 double dMinDist = ptNearest.
distanceTo( ptTest );
1852 const double dZeroDist = 1e-15;
1854 OdUInt32 iNumSeg = this->_numSegments();
1855 if ( ( iNumSeg > 0 ) && (dMinDist > dZeroDist) )
1862 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1864 this->_getSegment( iSeg, ImplSeg );
1866 double dSegParam = ImplSeg.nearestParam( ptTest, &ptTmp );
1870 if ( dDist < dMinDist )
1874 dNearestParam = iSeg + dSegParam;
1877 if ( dMinDist <= dZeroDist )
1884 *pptNearest = ptNearest;
1886 return dNearestParam;
1891template <
class TContourData >
1895 *pbOnBorder =
false;
1897 if ( this->_empty() )
1900 if ( !this->_closed() )
1903 bool bInside =
false;
1906 OdUInt32 iNumSeg = this->_numSegments();
1912 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1914 this->_getSegment( iSeg, ImplSeg );
1916 bool bOnSegment =
false;
1917 OdUInt32 iCount = ImplSeg.intersectXRay( rPoint, &bOnSegment, gTol );
1929 else if ( !this->_empty() )
1932 bInside =
BulgeSeg2D( this->_vertex(0).point(), this->_vertex(0).point() ).
isOn( rPoint, 0, gTol);
1934 *pbOnBorder = bInside;
1944template <
class TContourData >
1947 OdUInt32 iNumSegs = this->_numSegments();
1949 if ( iNumSegs <= 1 )
1954 if ( iNumSegs > 16 && !bExcludeTouch )
1956 bool bIntersects =
false;
1970 for (
OdUInt32 iSegA = 0; iSegA < iNumSegs; iSegA++ )
1972 this->_getSegment( iSegA, ImplSegA );
1974 for (
OdUInt32 iSegB = 0; iSegB < iSegA; iSegB++ )
1976 this->_getSegment( iSegB, ImplSegB );
1978 OdUInt32 iCrosses = ImplSegA.intersect( ImplSegB, &(XPt[0]), &(XPt[1]), gTol );
1984 if(bExcludeTouch && (iSegA != iNumSegs-1 || iSegB != 0) && iCrosses == 1 &&
Intersection::eitTouch == XPt[0].eType && !this->areEqualParams( iSegB + XPt[0].dParamB, iSegA + XPt[0].dParamA, 1e-14 ))
1986 const bool bAisTouchEnd =
OdEqual(XPt[0].dParamA, 1., 1e-10);
1987 const bool bAisTouchBeg =
OdEqual(XPt[0].dParamA, 0., 1e-10);
1989 const bool bBisTouchEnd =
OdEqual(XPt[0].dParamB, 1., 1e-10);
1990 const bool bBisTouchBeg =
OdEqual(XPt[0].dParamB, 0., 1e-10);
1992 const bool bAisTouch = bAisTouchEnd || bAisTouchBeg;
1993 const bool bBisTouch = bBisTouchEnd || bBisTouchBeg;
1994 if(bAisTouch && bBisTouch)
1996 const OdGeVector2d vA1 = bAisTouchEnd ? ImplSegA.startPt() - ImplSegA.endPt() : ImplSegA.endPt() - ImplSegA.startPt();
1997 int iNext = ((iSegA + (bAisTouchEnd ? 1 : -1)) + iNumSegs) % iNumSegs;
1999 this->_getSegment( iNext, ImplNext );
2000 const OdGeVector2d vA2 = bAisTouchEnd ? ImplNext.endPt() - ImplSegA.endPt() : ImplNext.startPt() - ImplSegA.startPt();
2002 const OdGeVector2d vB1 = bBisTouchEnd ? ImplSegB.startPt() - ImplSegB.endPt() : ImplSegB.endPt() - ImplSegB.startPt();
2003 iNext = ((iSegB + (bBisTouchEnd ? 1 : -1)) + iNumSegs) % iNumSegs;
2004 this->_getSegment( iNext, ImplNext );
2005 const OdGeVector2d vB2 = bBisTouchEnd ? ImplNext.endPt() - ImplSegB.endPt() : ImplNext.startPt() - ImplSegB.startPt();
2022 if((angB1 < angA && angB2 < angA) || (angB1 > angA && angB2 > angA))
2029 int iNext = ((iSegA + (bAisTouchEnd ? 1 : -1)) + iNumSegs) % iNumSegs;
2031 this->_getSegment( iNext, ImplNext );
2032 const OdGePoint2d pt1 = bAisTouchEnd ? ImplNext.endPt() : ImplNext.startPt();
2033 const OdGePoint2d pt2 = bAisTouchEnd ? ImplSegA.startPt() : ImplSegA.endPt();
2035 OdGeVector2d vLine = ImplSegB.endPt() - ImplSegB.startPt();
2036 const double sign1 = vLine.
crossProduct(pt1 - ImplSegB.startPt());
2037 const double sign2 = vLine.
crossProduct(pt2 - ImplSegB.startPt());
2038 if(sign1*sign2 > -1e-14)
2045 int iNext = ((iSegB + (bBisTouchEnd ? 1 : -1)) + iNumSegs) % iNumSegs;
2047 this->_getSegment( iNext, ImplNext );
2048 const OdGePoint2d pt1 = bBisTouchEnd ? ImplNext.endPt() : ImplNext.startPt();
2049 const OdGePoint2d pt2 = bBisTouchEnd ? ImplSegB.startPt() : ImplSegB.endPt();
2051 OdGeVector2d vLine = ImplSegA.endPt() - ImplSegA.startPt();
2052 const double sign1 = vLine.
crossProduct(pt1 - ImplSegA.startPt());
2053 const double sign2 = vLine.
crossProduct(pt2 - ImplSegA.startPt());
2054 if(sign1*sign2 > -1e-14)
2063 for (
OdUInt32 iC = 0; iC < iCrosses; iC++ )
2065 if ( !XPt[iC].eType )
2074 if ( this->areEqualParams( iSegB + XPt[iC].dParamB, iSegA + XPt[iC].dParamA, 1e-14 ) )
2077 double dDist = this->signedMinDistByParams( iSegB + XPt[iC].dParamB, iSegA + XPt[iC].dParamA );
2090template <
class TContourData >
2093 bool bValidRegion =
false;
2097 return bValidRegion;
2100template <
class TContourData >
2107 const OdUInt32 numVertices = this->numVerts();
2109 for(
OdUInt32 uVertexIdx = 0; uVertexIdx < numVertices; uVertexIdx++)
2111 this->getVertexAt(uVertexIdx, &ptVertex);
2113 bool fOnBorder =
false;
2114 if(!c2dOuter.
contains(ptVertex, &fOnBorder))
2117 if(!fAllowBordersTouch && fOnBorder)
2125template <
class TContourData >
2127 std::vector< Intersection > & vecPoints,
2130 if ( this->_empty() )
2137 OdUInt32 iNumSegs = this->_numSegments();
2146 for (
OdUInt32 iSeg = 0; iSeg < iNumSegs; iSeg++ )
2148 this->_getSegment( iSeg, ImplSeg );
2150 OdUInt32 iCrosses = ImplSeg.intersect( rSegB, &(XPt[0]), &(XPt[1]), gTol );
2154 for (
OdUInt32 iC = 0; iC < iCrosses; iC++ )
2161 vecPoints.push_back( XPt[iC] );
2165 else if ( this->_numVerts() > 0 )
2167 const OdGePoint2d & ptVert = this->_vertex(0).point();
2170 if ( rSegB.
isOn( ptVert, &dBParam, gTol ) )
2177 vecPoints.push_back( XPt[0] );
2181 return (
OdUInt32)vecPoints.size() - iOrigCrossCount;
2187template <
class TContourData >
2189 std::vector< Intersection > & vecPoints,
2192 if ( this->_empty() || rContB.
isEmpty() )
2195 OdUInt32 iNumSegs = this->_numSegments();
2199 OdUInt32 iCrossCount = iOrigCrossCount;
2208 return (
OdUInt32)vecPoints.size() - iOrigCrossCount;
2218 for (
OdUInt32 iSeg = 0; iSeg < iNumSegs; iSeg++ )
2220 this->_getSegment( iSeg, ImplSeg );
2223 rContB.
intersect( ImplSeg, vecPoints, gTol );
2227 while ( iCrossCount < vecPoints.size() )
2231 double dBParam = rCross.
dParamA;
2243 else if ( this->_numVerts() > 0 )
2246 BulgeSeg2D ASeg( this->_vertex(0).point(), this->_vertex(0).point() );
2249 rContB.
intersect( ASeg, vecPoints, gTol );
2251 while ( iCrossCount < vecPoints.size() )
2261 return iCrossCount - iOrigCrossCount;
2265template <
class TContourData >
2269 std::vector< Intersection > & vecPoints,
2275 OdUInt32 iNumSegs = this->_numSegments();
2296 for (
OdUInt32 iSeg = 0; iSeg < iNumSegs; iSeg++ )
2298 this->_getSegment( iSeg, ImplSeg );
2300 OdUInt32 iCrosses = ImplSeg.intersectLine( ptLineOrigin, vLineDir, &(XPt[0]), &(XPt[1]), gTol );
2306 for (
OdUInt32 iC = 0; iC < iCrosses; iC++ )
2313 vecPoints.push_back( XPt[iC] );
2318 else if ( this->_numVerts() > 0 )
2320 BulgeSeg2D ASeg( this->_vertex(0).point(), this->_vertex(0).point() );
2328 vecPoints.push_back( XPt[0] );
2332 return (
OdUInt32)vecPoints.size() - iOrigCrossCount;
2336template <
class TContourData >
2347 bool bExplodeRequired =
false;
2355 bExplodeRequired =
true;
2359 if ( bExplodeRequired )
2363 this->explodeTo( *
this, devDeviation );
2366 OdUInt32 iNumVerts = this->_numVerts();
2367 if ( this->_numVerts() <= 0 )
2370 bool bInverse = ( geMatrix.
det() < 0 );
2372 for (
OdUInt32 iVert = 0; iVert<iNumVerts; iVert++ )
2375 rVert.point().transformBy( geMatrix );
2377 rVert.bulge() = -rVert.bulge();
2380 this->_setModifiedAll();
2387template <
class TContourData >
2390 OdUInt32 iNumVerts = this->_numVerts();
2391 if ( this->_numVerts() <= 0 )
2394 if ( ! this->_closed() )
2399 for (
OdUInt32 iS = 0; iS < iSwapNum; iS++ )
2402 OdGePoint2d& rPtB = this->_vertex(iNumVerts - 1 - iS).point();
2404 std::swap( rVertA.point(), rPtB );
2406 TVertexData & rVertB = this->_vertex(iNumVerts - 2 - iS);
2408 std::swap( rVertA.bulge(), rVertB.bulge() );
2409 std::swap( rVertA.attributes(), rVertB.attributes() );
2418 OdUInt32 iPSwapNum = (iNumVerts-1)/2;
2419 for (
OdUInt32 iS = 0; iS < iPSwapNum; iS++ )
2422 OdGePoint2d& rPtB = this->_vertex(iNumVerts - iS - 1).point();
2423 std::swap( rPtA, rPtB );
2430 for (
OdUInt32 iS = 0; iS < iBSwapNum; iS++ )
2433 TVertexData & rVertB = this->_vertex(iNumVerts - iS - 1);
2435 std::swap( rVertA.bulge(), rVertB.bulge() );
2436 std::swap( rVertA.attributes(), rVertB.attributes() );
2443 for (
OdUInt32 i = 0, iSize = numVerts(); i < iSize; i++ )
2446 rVert.bulge() = -rVert.bulge();
2447 rVert.attributes().reverse();
2451 this->_setModifiedAll();
2458template <
class TContourData >
2461 OdUInt32 iNumVerts = this->_numVerts();
2462 if ( this->_numVerts() <= 1 )
2470 for (
OdUInt32 iVert = 1; iVert<iNumVerts; iVert++)
2473 if ( rThisVert.point().isEqualTo( pPrevVert->point(), gTol ) )
2476 pPrevVert->bulge() = rThisVert.bulge();
2477 pPrevVert->attributes() = rThisVert.attributes();
2481 pPrevVert = & this->_vertex(iNumHandled);
2482 if ( iNumHandled < iVert )
2483 *pPrevVert = rThisVert;
2489 if ( this->_closed() )
2491 if ( this->_vertex(0).point().isEqualTo( pPrevVert->point(), gTol ) )
2499 if ( iNumHandled < (iNumVerts-1) )
2500 this->_vertex(iNumHandled) = this->_vertex( iNumVerts-1 );
2503 if ( iNumHandled < iNumVerts )
2506 this->_resize( iNumHandled );
2507 this->_setModifiedAll();
2512template <
class TContourData >
2519template <
class TContourData >
2525 bool bThisDest = ( ((
const IContour2D*)
this) == &rDestCont );
2527 bool bClosed = this->_closed();
2529 OdUInt32 iNumVerts = this->_numVerts();
2530 OdUInt32 iNumSegs = this->_numSegments();
2537 rDestCont.
set( *
this );
2548 typedef std::pair< OdUInt32, Attributes2D > SegDataPair;
2549 std::vector< SegDataPair > vecAttributes;
2551 vecAttributes.
reserve( iNumVerts + 1);
2552 vecPoints.
reserve( iNumVerts );
2557 bool bHasArcs =
false;
2559 for (
OdUInt32 iSeg = 0; iSeg < iNumSegs; iSeg++ )
2561 this->_getSegment( iSeg, ImplSeg );
2564 vecAttributes.push_back( SegDataPair( vecPoints.
size(), Attr ) );
2566 vecPoints.
push_back( ImplSeg.startPt() );
2568 if ( ImplSeg.type() ==
estArc )
2571 vecAttributes.back().second.setExplodedArc(
true).metadata() |= uArcMetadata;
2573 eRes = arcSeg.
set( ImplSeg );
2585 for (
OdUInt32 iPt = 1; iPt<iSegmentCount; iPt++ )
2587 eRes = arcSeg.
getPoint(
double(iPt)/iSegmentCount, ptVertex );
2599 const TVertexData & rLast = this->_vertex( iNumVerts-1 );
2600 FMGE_ASSERT( ImplSeg.endPt().isEqualTo( rLast.point() ) );
2602 vecAttributes.push_back( SegDataPair( vecPoints.
size(), rLast.attributes() ) );
2614 rDestCont.
set( *
this );
2627 for (
OdUInt32 uI = 1; uI < vecAttributes.size(); ++uI )
2629 const Attributes2D& rAttr = vecAttributes[ uI-1 ].second;
2632 OdUInt32 uVert = vecAttributes[ uI-1 ].first;
2633 OdUInt32 uLastVert = vecAttributes[ uI ].first;
2635 for ( ; uVert < uLastVert; ++uVert )
2647template <
class TContourData >
2652 Result eRes = _param2IdxParam( dParam, iIndex, dSegParam );
2657 eRes = this->_getSegment( iIndex, ImplSeg );
2663 double dLen = ImplSeg.length();
2669 if ( dSegParam*dLen <= dTol )
2674 else if ( (1.0 - dSegParam)*dLen <= dTol )
2677 return (iIndex+1) % this->_numVerts();
2685 eRes = ImplSeg.getPoint( dSegParam, ptSplit);
2692 if ( ImplSeg.type()==
estArc )
2695 double dAngle = ImplSeg.arcAngle();
2696 double dBulge1 = ::tan( 0.25 * dAngle * dSegParam );
2697 double dBulge2 = ::tan( 0.25 * dAngle * (1.0 - dSegParam) );
2701 this->_vertex( iIndex ).bulge() = dBulge1;
2702 this->_setModifiedSegs( iIndex );
2703 eRes = this->_insertVerticesAt(iNewIndex, 1, &ptSplit, &dBulge2, &Attr );
2708 if ( ImplSeg._bulge() != 0.0 )
2710 this->_vertex( iIndex ).bulge() = 0.0;
2711 this->_setModifiedSegs( iIndex );
2714 eRes = this->_insertVerticesAt(iNewIndex, 1, &ptSplit, 0, &Attr );
2725template <
class TContourData >
2729 if ( uCount<1 || !pdParams )
2732 typedef std::pair< OdUInt32, double > SegOffsPair;
2733 std::vector< SegOffsPair > vecParams;
2734 vecParams.reserve( uCount );
2742 for (
OdUInt32 uP = 0; uP < uCount; ++uP )
2744 Result eRes = _param2IdxParam( pdParams[uP], currSO.first, currSO.second );
2747 vecParams.push_back( currSO );
2750 std::sort( vecParams.begin(), vecParams.end() );
2754 if ( !vecParams.empty() )
2760 std::vector< double > vecSegParams;
2761 std::vector< OdGePoint2d > vecSegPoints;
2762 std::vector< double > vecSegBulges;
2763 std::vector< Attributes2D > vecSegAttributes;
2773 OdUInt32 uSeg = vecParams[uSBegin].first;
2774 while ( uSBegin > 0 && ( uSeg == vecParams[uSBegin-1].first ) )
2778 eRes = this->_getSegment( uSeg, ImplSeg );
2780 currSeg.
set( ImplSeg );
2783 double dLen = currSeg.
length();
2787 vecSegParams.resize( 0 );
2789 for (
OdUInt32 uP = uSBegin; uP < uSEnd; ++uP )
2791 double dSegParam = vecParams[uP].second;
2792 if ( dSegParam*dLen > dTol && (1.0 - dSegParam)*dLen > dTol )
2795 if ( vecSegParams.empty()
2796 || !
OdEqual( vecSegParams.back(), dSegParam, dTol ) )
2799 vecSegParams.push_back( dSegParam );
2805 if ( !vecSegParams.empty() )
2810 vecSegPoints.resize( uNewNum );
2812 for (
OdUInt32 uP = 0 ; uP < uNewNum; ++uP )
2814 eRes = currSeg.
getPoint( vecSegParams[uP], vecSegPoints[uP] );
2821 vecSegAttributes.resize( 0 );
2824 vecSegAttributes.resize( uNewNum, currSeg.
attributes() );
2825 pAttributes = &( vecSegAttributes.front() );
2832 vecSegBulges.resize( uNewNum+1 );
2833 vecSegParams.push_back( 1.0 );
2835 double dAngle4 = currSeg.
arcAngle()/4.0;
2837 double dPrevParam = 0;
2838 for (
OdUInt32 uP = 0; uP <= uNewNum; ++uP )
2840 vecSegBulges[ uP ] = ::tan( dAngle4 * ( vecSegParams[uP] - dPrevParam ) );
2841 dPrevParam = vecSegParams[uP];
2845 this->_vertex( uSeg ).bulge() = vecSegBulges[0];
2846 this->_setModifiedSegs( uSeg );
2849 eRes = this->_insertVerticesAt( uSeg + 1, uNewNum,
2850 & ( vecSegPoints[0] ),
2851 & ( vecSegBulges[1] ),
2861 if ( ImplSeg._bulge() != 0.0 )
2863 this->_vertex( uSeg ).bulge() = 0.0;
2864 this->_setModifiedSegs( uSeg );
2868 eRes = this->_insertVerticesAt( uSeg + 1, uNewNum, &( vecSegPoints.front() ), 0, pAttributes );
2883template <
class TContourData >
2886 return _createVerticesAt( (
OdUInt32)vecParams.size(), &( vecParams.front() ), gTol );
2889template <
class TContourData>
2892 return _createVerticesAt(
size, vecParams, gTol );
2896template <
class TContourData >
2898 const double dParamA,
const double dParamB,
2900 OdUInt32& iNumPeriodsAB,
const double dParamTol )
const
2904 OdUInt32 iNumSegs = this->_numSegments();
2905 if ( iNumSegs <= 0 )
2908 dSegParamA = dSegParamB = 0;
2909 if ( this->_numVerts() > 0 &&
OdZero(dParamA, dParamTol) &&
OdZero(dParamB, dParamTol) )
2915 bool bReverse = (dParamA > dParamB);
2919 double adSegParams[2];
2921 for (
int i = 0; i<2; ++i )
2924 adSegParams[i] = ::modf( i==
int(bReverse) ? dParamA : dParamB, &dIdx );
2925 aiIdx[i] = long( ::floor( dIdx + 0.5 ) );
2926 if ( adSegParams[i] < 0 )
2928 adSegParams[i] += 1;
2936 if ( adSegParams[0] >= 1.0-dParamTol )
2938 adSegParams[0] = 0.0;
2941 else if ( adSegParams[0] <= dParamTol )
2943 adSegParams[0] = 0.0;
2946 if ( adSegParams[1] <= dParamTol )
2948 adSegParams[1] = 1.0;
2951 else if ( adSegParams[1] >= 1.0-dParamTol )
2953 adSegParams[1] = 1.0;
2959 if ( aiIdx[0] > aiIdx[1] || ( aiIdx[0] == aiIdx[1] && adSegParams[0] >= adSegParams[1] ) )
2962 "Critical floating-point inaccuracy!" );
2964 aiIdx[1] = aiIdx[0];
2965 adSegParams[1] = adSegParams[0];
2971 if ( this->_closed() )
2975 ldiv_t aPeriodsIdxs[2];
2976 for (
int i=0; i<2; ++i )
2978 ldiv_t& rDest = aPeriodsIdxs[i];
2979 rDest = ::ldiv( aiIdx[i],
long(iNumSegs) );
2980 if ( rDest.rem < 0 )
2982 rDest.rem += long(iNumSegs);
2987 iNumPeriodsAB = aPeriodsIdxs[ !bReverse ].quot - aPeriodsIdxs[ bReverse ].quot;
2988 uIdxA =
OdUInt32( aPeriodsIdxs[ bReverse ].rem );
2989 uIdxB =
OdUInt32( aPeriodsIdxs[!bReverse ].rem );
2990 dSegParamA = adSegParams[ bReverse ];
2991 dSegParamB = adSegParams[!bReverse ];
2998 for (
int i=0; i<2; ++i )
3002 if ( aiIdx[i] == -1 && adSegParams[i] >= (1.0-dParamTol) )
3005 adSegParams[i] = 0.0;
3010 else if ( aiIdx[i] >=
long(iNumSegs) )
3012 if ( aiIdx[i] ==
long(iNumSegs) && adSegParams[i] <= dParamTol )
3014 aiIdx[i] = long(iNumSegs)-1;
3015 adSegParams[i] = 1.0;
3023 uIdxA =
OdUInt32( aiIdx[ bReverse ] );
3024 uIdxB =
OdUInt32( aiIdx[!bReverse ] );
3025 dSegParamA = adSegParams[ bReverse ];
3026 dSegParamB = adSegParams[!bReverse ];
3034template <
class TContourData >
3038 Result eRes = this->_getSegment( iIndex, srcSeg );
3042 return worstResult( eRes, srcSeg.getSubSegment( dStartOffs, dEndOffs, rDestSeg ) );
3046template <
class TContourData >
3050 OdUInt32 iNumSegs = this->_numSegments();
3056 double adSegParams[2];
3059 bool bReverse = ( dStartParam > dEndParam );
3061 eRes = _paramRange2IdxParams(
3062 bReverse ? dEndParam : dStartParam,
3063 bReverse ? dStartParam : dEndParam,
3064 auSegIdxs[0], adSegParams[0], auSegIdxs[1], adSegParams[1], iNumPeriods, 1e-14 );
3071 double dOldLen = ( bReverse ? -1 : 1)*(dEndParam - dStartParam);
3072 double dNewLen = (auSegIdxs[1]+adSegParams[1]) - (auSegIdxs[0]+adSegParams[0]) + iNumPeriods*double(iNumSegs);
3080 if ( iNumPeriods < 0 || ( iNumPeriods==0 && auSegIdxs[0] > auSegIdxs[1] ) )
3082 FMGE_FAULT(
"Illegal values caused by buggy code or FP-inaccuracy!");
3090 Result tmpRes = this->_getSegment( auSegIdxs[bReverse], srcSeg );
3095 tmpRes = srcSeg.getPoint( adSegParams[bReverse], ptPoint );
3100 BulgeSeg2D( ptPoint, ptPoint, 0.0, srcSeg.attributes() ),
3107 if ( auSegIdxs[0]==auSegIdxs[1] && 0==iNumPeriods )
3111 auSegIdxs[0], adSegParams[ bReverse ], adSegParams[ !bReverse ], gSingleSeg ) );
3121 if ( iNumSegs <= 0 )
3129 eRes =
worstResult( eRes, _getSubSegment( auSegIdxs[0], adSegParams[0], 1.0, gBoundarySegs[0] ) );
3130 eRes =
worstResult( eRes, _getSubSegment( auSegIdxs[1], 0.0, adSegParams[1], gBoundarySegs[1] ) );
3136 aiUnbrokenSegs[0] = auSegIdxs[0] + 1;
3137 aiUnbrokenSegs[1] = auSegIdxs[1] - 1 + iNumPeriods*
OdUInt32(iNumSegs);
3139 OdUInt32 iNumUnbroken = ( aiUnbrokenSegs[1] - aiUnbrokenSegs[0] + 1 );
3163 for (
OdUInt32 iSeg = aiUnbrokenSegs[0]; iSeg <= aiUnbrokenSegs[1]; ++iSeg )
3166 Result tmpRes = this->_getSegment( iIndex, srcSeg );
3172 tmpRes = rSubContour.
appendSegment( srcSeg._bulge(), srcSeg._endPt(), srcSeg._attr() );
3181 for (
OdUInt32 iSeg = aiUnbrokenSegs[1]; iSeg >= aiUnbrokenSegs[0]; --iSeg )
3184 const TVertexData & rVert = this->_vertex( iIndex );
3187 Result tmpRes = rSubContour.
appendSegment( -rVert.bulge(), rVert.point(), rVert.attributes().getReversed() );
3204template <
class TContourData >
3206 double dStartParam,
double dEndParam,
IContour2D & rSubContour,
const OdGeTol & gTol )
const
3209 if ( _isEqualToThis(rSubContour) )
3212 rSubContour.
reset();
3213 return _appendSubContourTo( dStartParam, dEndParam, rSubContour, gTol );
3216template <
class TContourData >
3218 double dStartParam,
double dEndParam,
IContour2D & rSubContour,
const OdGeTol & gTol )
const
3221 if ( _isEqualToThis(rSubContour) )
3224 return _appendSubContourTo( dStartParam, dEndParam, rSubContour, gTol );
3229template <
class TContourData >
3232 FMGE_ASSERT( !_isEqualToThis(rDest) && (&rDest != &rSubContour) );
3233 if ( _isEqualToThis(rDest) || &rDest == &rSubContour )
3250 if ( !isOn( aSubEnds[0], &(adParams[0]), gTol )
3251 ||!isOn( aSubEnds[1], &(adParams[1]), gTol ) )
3257 bool bEqualEnds = aSubEnds[0].
isEqualTo( aSubEnds[1], gTol );
3258 double dParamLength = double( this->_numSegments() );
3260 if ( this->_closed() )
3264 double dLoopStart = adParams[1];
3265 double dLoopEnd = adParams[0];
3268 dLoopEnd = dLoopStart + dParamLength;
3269 else if ( dLoopEnd < dLoopStart )
3270 dLoopEnd += dParamLength;
3272 eRes = _appendSubContourTo( dLoopStart, dLoopEnd, rDest, gTol );
3288 adParams[1] = adParams[0];
3289 else if ( adParams[0] > adParams[1] )
3294 if ( adParams[0] > 0 )
3295 eRes = _appendSubContourTo( 0.0, adParams[0], rDest, gTol );
3300 if (
isOk(eRes) && ( adParams[1] < dParamLength ) )
3301 eRes = _appendSubContourTo( adParams[1], dParamLength, rDest, gTol );
#define FMGE_ASSERTMSG(x, c)
#define FMGE_MUSTNOTEXECUTE
bool OdEqual(double x, double y, double tol=1.e-10)
bool OdZero(double x, double tol=1.e-10)
bool OdGreaterOrEqual(double x, double y, double tol=1.e-10)
static FMGEOMETRY_API_STATIC const Attributes2D kNull
Result set(const CachedSeg2D &rSeg)
virtual const Attributes2D & attributes() const
virtual double arcAngle() const
virtual double arcRadius() const
virtual SegmentType type() const
virtual double length() const
virtual Result getPoint(double dParam, OdGePoint2d &ptPoint) const
virtual OdUInt32 intersectLine(const OdGePoint2d &ptLineOrigin, const OdGeVector2d &vLineDir, Intersection *pInt1=0, Intersection *pInt2=0, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual double integrate(const OdGePoint2d &ptOrigin=OdGePoint2d::kOrigin) const
virtual bool isOn(const OdGePoint2d &ptTest, double *pdParam=0, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual const Attributes2D & attributes() const =0
virtual Result set(const OdGePoint2d &ptA, const OdGePoint2d &ptB, double dBulge, const Attributes2D &rAttr)=0
virtual const OdGePoint2d & endPt() const =0
virtual const OdGePoint2d & startPt() const =0
virtual double bulge() const =0
virtual bool isOn(const OdGePoint2d &ptTest, double *pdParam=0, const OdGeTol &gTol=FMGeGbl::gTol) const =0
virtual OdUInt32 intersect(const IBulgeSeg2D &rSegB, std::vector< Intersection > &vecPoints, const OdGeTol &gTol=FMGeGbl::gTol) const =0
virtual Result appendSegment(const IBulgeSeg2D &rSeg, bool bShiftToHit=false, const OdGeTol &gTol=FMGeGbl::gTol)=0
virtual Result getVertexAt(OdUInt32 iIndex, OdGePoint2d *pptPoint, double *pdBulge=0, Attributes2D *pAttr=0) const =0
virtual bool isClosed() const =0
virtual void set(const IContour2D &rSrcCont)=0
virtual Result setAttributesAt(OdUInt32 iIndex, const Attributes2D &rAttr)=0
virtual Result getStartPoint(OdGePoint2d &ptPoint) const =0
virtual void reserveVertices(OdUInt32 iReservedSize)=0
virtual bool setClosedIfEndsAreEqual(const OdGeTol &gTol=FMGeGbl::gTol)=0
virtual bool hasArcs() const =0
virtual bool isEmpty() const =0
virtual void setClosed(bool bClosed=true)=0
virtual bool contains(const OdGePoint2d &rPoint, bool *pbOnBorder=0, const OdGeTol &gTol=FMGeGbl::gTol) const =0
virtual OdUInt32 numVerts() const =0
virtual Result appendContour(const IContour2D &rCont, bool bCloseGap=false, double dMaxGap=1e99)=0
virtual Result getEndPoint(OdGePoint2d &ptPoint) const =0
virtual Result appendVertices(const OdGePoint2dArray &vecSource)=0
virtual OdUInt32 numSegments() const =0
virtual Result getPointAt(OdUInt32 iIndex, OdGePoint2d &ptPoint) const
virtual Result replaceSubContourTo(IContour2D &rDest, const IContour2D &rSubContour, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual OdUInt32 intersect(const IContour2D &rContB, std::vector< Intersection > &vecPoints, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual bool isSelfIntersecting(const OdGeTol &gTol=FMGeGbl::gTol, bool bExcludeTouch=false) const
Result _getSubSegment(OdUInt32 iIndex, double dStartOffs, double dEndOffs, IBulgeSeg2D &rDestSeg) const
Result _param2dist(double dParam, double &dDist) const
virtual Result appendSegment(double dBulge, const OdGePoint2d &ptNewEnd, const Attributes2D &rAttr=Attributes2D::kNull)
virtual OdUInt32 intersect(const IBulgeSeg2D &rSegB, std::vector< Intersection > &vecPoints, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result appendContour(const IContour2D &rCont, bool bCloseGap=false, double dMaxGap=1e99)
virtual Result getInternalPoint(OdGePoint2d &rPoint, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual double signedMinDistByParams(double dParam1, double dParam2) const
virtual Result setVertexAt(OdUInt32 iIndex, const OdGePoint2d &ptPoint, double dBulge)
virtual bool isClosed() const
virtual Result removeVertexAt(OdUInt32 iIndex)
virtual double signedMinDist(double dDist1, double dDist2) const
virtual Result getSubContour(double dStartParam, double dEndParam, IContour2D &rSubContour, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result getNormalizedDist(double &dDist) const
virtual double nearestParam(const OdGePoint2d &ptTest, OdGePoint2d *ptNearest=0) const
virtual OdUInt32 createVertexAt(double dParam, const OdGeTol &gTol=FMGeGbl::gTol)
Result _dist2IdxParam(double dDist, OdUInt32 &iIndex, double &dSegParam) const
virtual void deleteCoincident(const OdGeTol &gTol=FMGeGbl::gTol)
Result _param2IdxParam(double dParam, OdUInt32 &iIndex, double &dSegParam) const
virtual Result appendVertex(const OdGePoint2d &ptStart, double dBulge=0.0, const Attributes2D &rAttr=Attributes2D::kNull)
virtual IContour2D * clone() const
virtual OdUInt32 numSegments() const
Result _normalizeParam(double &dParam) const
Result _createVerticesAt(OdUInt32 uCount, const double *pdParams, const OdGeTol &gTol)
virtual Result setBulgeAt(OdUInt32 iIndex, double dBulge)
virtual Result getSegmentAt(OdUInt32 iIndex, IBulgeSeg2D &rSegment) const
virtual void reserveVertices(OdUInt32 iReservedSize)
virtual bool isConvex() const
Result _appendSubContourTo(double dStartParam, double dEndParam, IContour2D &rSubContour, const OdGeTol &gTol) const
virtual OdUInt32 intersectLine(const OdGePoint2d &ptLineOrigin, const OdGeVector2d &vLineDir, std::vector< Intersection > &vecPoints, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result getInternalAngleAt(OdUInt32 iIndex, double &dAngle) const
virtual Result appendSubContourTo(double dStartParam, double dEndParam, IContour2D &rSubContour, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result createVerticesAt(OdUInt32 size, const double *vecParams, const OdGeTol &gTol=FMGeGbl::gTol)
virtual Result getSegmentAt(OdUInt32 iIndex, OdGePoint2d &ptStart, OdGePoint2d &ptEnd, double &dBulge) const
virtual double signedArea() const
virtual Result explodeTo(IContour2D &rDestCont, const DeviationParams &devDeviation=FMGeGbl::gDefDev, OdIntPtr uArcMetadata=0) const
virtual Result setAttributesAt(OdUInt32 iIndex, const Attributes2D &rAttr)
virtual bool isEmpty() const
virtual Result transformBy(const OdGeMatrix2d &geMatrix, const DeviationParams &devDeviation=FMGeGbl::gDefDev)
virtual Result appendSegment(const IBulgeSeg2D &rSeg, bool bShiftToHit=false, const OdGeTol &gTol=FMGeGbl::gTol)
virtual Result getParamAtDist(double dDist, double &dParam) const
virtual Result getStartPoint(OdGePoint2d &ptPoint) const
virtual OdUInt32 numVerts() const
virtual Result getPoint(double dParam, OdGePoint2d &ptPoint) const
virtual Result getDistAtParam(double dParam, double &dDist) const
virtual Result getNormalizedParam(double &dParam) const
virtual Attributes2D & attributes4UAt(OdUInt32 iIndex)
virtual SegmentType segmentType(OdUInt32 iIndex) const
virtual void setClosed(bool bClosed=true)
virtual bool setClosedIfEndsAreEqual(const OdGeTol &gTol=FMGeGbl::gTol)
virtual bool areEqualDists(double dDist1, double dDist2, const double dTol=FMGeGbl::gTol.equalPoint()) const
virtual Result getBulgeAt(OdUInt32 iIndex, double &dBulge) const
Result _paramRange2IdxParams(const double dParamA, const double dParamB, OdUInt32 &uIdxA, double &dSegParamA, OdUInt32 &uIdxB, double &dSegParamB, OdUInt32 &iNumPeriodsAB, const double dParamTol=DBL_EPSILON) const
virtual Result getPointAtDist(double dDist, OdGePoint2d &ptPoint) const
virtual bool contains(const OdGePoint2d &rPoint, bool *pbOnBorder=0, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual void set(const IContour2D &rSrcCont)
virtual ContourImplClass implClass() const
virtual bool hasArcs() const
TContourData::VertexData TVertexData
virtual Result getEndPoint(OdGePoint2d &ptPoint) const
virtual Result createVerticesAt(const std::vector< double > &vecParams, const OdGeTol &gTol=FMGeGbl::gTol)
virtual Result addVertexAt(OdUInt32 iIndex, const OdGePoint2d &ptStart, double dBulge=0.0, const Attributes2D &rAttr=Attributes2D::kNull)
virtual Result appendVertices(const OdGePoint2dArray &vecSource)
TContour2DImpl(const TContour2DImpl &rSrcCont)
virtual const Attributes2D & attributesAt(OdUInt32 iIndex) const
virtual bool isInsideContour(const IContour2D &c2dOuter, bool fAllowBordersTouch=false, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result getArcSegAt(OdUInt32 iIndex, OdGeCircArc2d &geArc) const
TContourData::ImplSeg2D TImplSeg2D
virtual Result getLineSegAt(OdUInt32 iIndex, OdGeLineSeg2d &geLine) const
virtual OdIntPtr metadataAt(OdUInt32 iIndex) const
virtual Result getTangent(double dParam, OdGeVector2d &vTangent) const
bool _isEqualToThis(const IContour2D &rC) const
virtual double length() const
virtual bool areEqualParams(double dParam1, double dParam2, const double dTol=1e-10) const
virtual void mergeSegments(int iMergeFlags=0, const OdGeTol &gTol=FMGeGbl::gTol)
virtual bool isOn(const OdGePoint2d &ptTest, double *pdParam=0, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result addExtents(OdGeExtents2d &geExtents) const
virtual Result appendVertices(OdUInt32 size, const OdGePoint2d *vecSource, const double *bulgeSource)
virtual Result getVertexAt(OdUInt32 iIndex, OdGePoint2d *pptPoint, double *pdBulge=0, Attributes2D *pAttr=0) const
virtual Result setMetadataAt(OdUInt32 iIndex, OdIntPtr uNewData)
virtual Result setPointAt(OdUInt32 iIndex, const OdGePoint2d &ptPoint)
virtual bool isValidRegion(const OdGeTol &gTol=FMGeGbl::gTol) const
void push_back(const T &value)
void reserve(size_type reserveLength)
OdGeExtents2d & addPoint(const OdGePoint2d &point)
OdGeExtents2d & addExt(const OdGeExtents2d &extents)
void getCoordSystem(OdGePoint2d &origin, OdGeVector2d &xAxis, OdGeVector2d &yAxis) const
bool isEqualTo(const OdGePoint2d &point, const OdGeTol &tol=OdGeContext::gTol) const
static GE_STATIC_EXPORT const OdGePoint2d kOrigin
double distanceTo(const OdGePoint2d &point) const
double equalVector() const
double equalPoint() const
double crossProduct(const OdGeVector2d &vect) const
bool isZeroLength(const OdGeTol &tol=OdGeContext::gTol) const
static GE_STATIC_EXPORT const OdGeVector2d kIdentity
double angleToCCW(const OdGeVector2d &vect) const
GLuint GLsizei GLsizei * length
Result fast_isValidRegion(const IContour2D &rContour, const OdGeTol &gTol, bool &bValidRegion)
Attributes2D & nullAttributesForUpdate()
Result fast_isSelfIntersecting(const IContour2D &rContour, const OdGeTol &gTol, bool &bIntersects)
Result fast_getInternalPoint(const IContour2D &rContour, OdGePoint2d &rPoint, const OdGeTol &gTol)
bool isError(Result eRes)
Result fast_intersect(const IContour2D &rContA, const IContour2D &rContB, std::vector< Intersection > &vecPoints, const OdGeTol &gTol)
void contour2d_mergeSegments(IContour2D &rContour, int iMergeFlags=0, const OdGeTol &gTol=FMGeGbl::gTol)
Result worstResult(Result eRes1, Result eRes2)
static FMGEOMETRY_API_STATIC OdUInt16 GetSegmentCount(double dAngle, double dRadius, const DeviationParams &devDeviation)
static FMGEOMETRY_API_STATIC DeviationParams gDefDev
static FMGEOMETRY_API_STATIC OdGeTol gTol