diff --git a/OffsetCurve3d.cpp b/OffsetCurve3d.cpp index 50cc9c3..495d92d 100644 --- a/OffsetCurve3d.cpp +++ b/OffsetCurve3d.cpp @@ -25,10 +25,11 @@ using namespace std ; -#define SAVECVRORIG 0 +#define SAVECRVORIG 0 #define SAVEOFFDIR 0 #define SAVECYL 0 -#if SAVECVRORIG || SAVEOFFDIR || SAVECYL +#define SAVEOFFSET 0 +#if SAVECRVORIG || SAVEOFFDIR || SAVECYL || SAVEOFFSET #include "/EgtDev/Include/EGkColor.h" #include "/EgtDev/Include/EGkGeoVector3d.h" vector vGeo ; @@ -87,7 +88,7 @@ OffsetCurve3d::Make( const PolyLine& PL, const VCT3DVECTOR& vOffDir, double dOff if ( ! pCrv->FromPolyLine( PL)) return false ; -#if SAVECVRORIG || SAVEOFFDIR +#if SAVECRVORIG || SAVEOFFDIR vGeo.clear() ; vCol.clear() ; @@ -103,6 +104,9 @@ OffsetCurve3d::Make( const PolyLine& PL, const VCT3DVECTOR& vOffDir, double dOff vCol.push_back( BLUE) ; } #endif + #if ! SAVECYL && ! SAVEOFFSET + SaveGeoObj( vGeo, vCol, "C:\\Temp\\curve offset 3d\\crvoffset.nge") ; + #endif #endif // verifico se la curva è un segmento di retta @@ -233,6 +237,7 @@ OffsetCurve3d::Make( const PolyLine& PL, const VCT3DVECTOR& vOffDir, double dOff double dProj = 1 ; if ( vtDirPrevOff.IsValid()) dProj = vtDirCurrOff * vtDirPrevOff ; + // prima di inserirlo controllo che il tratto non torni indietro if ( dProj > - 0.5 || vFlag[i] == OffsetCurve3d::AngType::ANG_SMOOTH_CONC) { // aggiungo tratto ICurveLine* pCL = CreateBasicCurveLine() ; @@ -261,18 +266,19 @@ OffsetCurve3d::Make( const PolyLine& PL, const VCT3DVECTOR& vOffDir, double dOff if ( ! AdjustConcavePartsInPath( pCrv, vOffsetCrvs, dOffDist)) return false ; -#if SAVECVRORIG || SAVEOFFDIR || SAVECYL - for ( int i = 0 ; i < ssize( vOffsetCrvs) ; ++i) { - vGeo.push_back( vOffsetCrvs[i].pCrv->Clone()) ; - if ( vOffsetCrvs[i].nFlag == OffsetCurve3d::AngType::ANG_SMOOTH_CONC) - vCol.push_back( GREEN) ; - else if ( vOffsetCrvs[i].nFlag == OffsetCurve3d::AngType::ANG_STR) - vCol.push_back( PURPLE) ; - else if ( vOffsetCrvs[i].nFlag == OffsetCurve3d::AngType::ANG_CVEX) - vCol.push_back( RED) ; - } +#if SAVEOFFSET || SAVECYL + #if SAVEOFFSET + for ( int i = 0 ; i < ssize( vOffsetCrvs) ; ++i) { + vGeo.push_back( vOffsetCrvs[i].pCrv->Clone()) ; + if ( vOffsetCrvs[i].nFlag == OffsetCurve3d::AngType::ANG_SMOOTH_CONC) + vCol.push_back( GREEN) ; + else if ( vOffsetCrvs[i].nFlag == OffsetCurve3d::AngType::ANG_STR) + vCol.push_back( PURPLE) ; + else if ( vOffsetCrvs[i].nFlag == OffsetCurve3d::AngType::ANG_CVEX) + vCol.push_back( RED) ; + } + #endif SaveGeoObj( vGeo, vCol, "C:\\Temp\\curve offset 3d\\crvoffset.nge") ; - return true ; #endif PtrOwner pCrvOffset( CreateBasicCurveComposite()) ; @@ -387,7 +393,7 @@ IsPointInsideCylinder( const Point3d& ptTest, const Cyl& offCyl, double dLinTol) bool AdjustConcavePartsInPath( const ICurveComposite* pCrv, vOffsetSeg& vOffsetCrvs, double dRad) { - const double dLinTol = 5 * EPS_SMALL ; + const double dLinTol = 10 * EPS_SMALL ; INTVECTOR vErase ; for ( int i = 0 ; i < ssize( vOffsetCrvs) ; ++i) { int nFlag = vOffsetCrvs[i].nFlag ; @@ -414,7 +420,7 @@ AdjustConcavePartsInPath( const ICurveComposite* pCrv, vOffsetSeg& vOffsetCrvs, vCyl.emplace_back( ptStart, vtHeight, dHeight, dRad, dLinTol) ; #if SAVECYL CurveArc ca ; ca.Set( ptStart, vtHeight, dRad) ; - ISurfTriMesh* pSurfTm = GetSurfTriMeshByExtrusion( &ca, vtHeight, false, 2 * EPS_SMALL) ; + ISurfTriMesh* pSurfTm = GetSurfTriMeshByExtrusion( &ca, vtHeight * dHeight, false, 2 * EPS_SMALL) ; vGeo.push_back( pSurfTm) ; vCol.push_back( LGRAY) ; #endif @@ -442,6 +448,12 @@ AdjustConcavePartsInPath( const ICurveComposite* pCrv, vOffsetSeg& vOffsetCrvs, if ( bToErase) { bErasedSomePart = true ; bErasedPrev = true ; + // se avevo un'interruzione nella zona da modificare, la colmo + if ( ! vInters.empty() && vInters.back() != vLines[j-1]) { + // aggiungo tutti i precedenti che mancano + for ( int h = vInters.back() + 1 ; h < vLines[j] ; ++h) + vInters.push_back( h) ; + } vInters.push_back( vLines[j]) ; if ( j < ssize( vLines) - 1) vInters.push_back( vLines[j+1]) ; diff --git a/ProjectCurveSurf.cpp b/ProjectCurveSurf.cpp index dc207ba..30151ef 100644 --- a/ProjectCurveSurf.cpp +++ b/ProjectCurveSurf.cpp @@ -81,24 +81,34 @@ AddPointsOnCorners( PNT5AXVECTOR& vPt5ax) Point3d ptInt ; if ( IntersLinePlane( ptEdge, vtEdge, 1, plPlane3, ptInt, false) == ILPT_YES) { // verifico se spigolo convesso o concavo - bool bConvex = (vPt5ax[i].ptP - vPt5ax[j].ptP) * vPt5ax[j].vtDir1 < 0 ; - bool bValidInters = true ; + double dProjPrev = ( vPt5ax[i].ptP - vPt5ax[j].ptP) * vPt5ax[j].vtDir1 ; + double dProjCurr = ( vPt5ax[j].ptP - vPt5ax[i].ptP) * vPt5ax[i].vtDir1 ; + bool bConvex = ( abs( dProjCurr) > abs( dProjPrev) ? dProjCurr < 0 : dProjPrev < 0) ; + bool bValidIntersAfterJ = true ; + bool bValidIntersBeforeI = true ; if ( i > 2) { - int k = i - 2 ; - // verifico la concavità anche tornando indietro lungo la linea - if ( ( ( vPt5ax[k].ptP - vPt5ax[j].ptP) * vPt5ax[i].vtDir1 < 0) != bConvex) { - LOG_WARN( GetEGkLogger(), "La superficie su cui si sta proiettando la curva ha delle normali incoerenti") - return false ; - } // verifico che l'intersezione sia tra i e j e non prima di j - bValidInters = ( ptInt - vPt5ax[j].ptP) * ( vPt5ax[j].ptP - vPt5ax[k].ptP) > 0 ; + int k = i - 2 ; + bValidIntersAfterJ = ( ptInt - vPt5ax[j].ptP) * ( vPt5ax[j].ptP - vPt5ax[k].ptP) > 0 ; } + if ( i < ssize( vPt5ax) - 1) { + // verifico anche che l'intersezione non sia dopo i + int h = i + 1 ; + bValidIntersBeforeI = ( ptInt - vPt5ax[i].ptP) * ( vPt5ax[h].ptP - vPt5ax[i].ptP) < 0 ; + } + bool bValidInters = ( bValidIntersAfterJ && bValidIntersBeforeI) ; // se convesso, metto due punti con direzione appena prima e appena dopo if ( bConvex) { Vector3d vtLine1 = ptInt - vPt5ax[j].ptP ; double dLen1 = vtLine1.Len() ; Vector3d vtLine2 = vPt5ax[i].ptP - ptInt ; double dLen2 = vtLine2.Len() ; - if ( dLen1 > 10 * EPS_SMALL && bValidInters) { + if ( dLen1 > 10 * EPS_SMALL && bValidIntersAfterJ) { Point5ax Pt5ax ; + if ( bValidInters) + Pt5ax.ptP = ptInt - vtLine1 / dLen1 * 2 * EPS_SMALL ; + else { + Vector3d vtNewLine = vPt5ax[i].ptP - vPt5ax[j].ptP ; vtNewLine.Normalize() ; + Pt5ax.ptP = vPt5ax[i].ptP - vtNewLine * 2 * EPS_SMALL ; + } Pt5ax.vtDir1 = vPt5ax[j].vtDir1 ; Pt5ax.vtDir2 = vPt5ax[j].vtDir2 ; Pt5ax.vtDirU = vPt5ax[j].vtDirU ; @@ -110,7 +120,7 @@ AddPointsOnCorners( PNT5AXVECTOR& vPt5ax) } else vPt5ax[j].nFlag = P5AX_CVEX ; - if ( dLen2 > 10 * EPS_SMALL) { + if ( dLen2 > 10 * EPS_SMALL && bValidIntersBeforeI) { Point5ax Pt5ax ; if ( bValidInters) Pt5ax.ptP = ptInt + vtLine2 / dLen2 * 2 * EPS_SMALL ;