diff --git a/BtlGeom.h b/BtlGeom.h index 33c0042..b51c6f9 100644 --- a/BtlGeom.h +++ b/BtlGeom.h @@ -152,6 +152,7 @@ class BtlGeom bool DoSewing( ISurfTriMesh* pStm, const Polygon3d& Polyg) ; bool TrimSurfTmWithBox( ISurfTriMesh* pStm) ; bool TrimFlatCurveWithBox( ICurve* pCurve) ; + bool TrimSegmentWithBox( Point3d& ptP1, Point3d& ptP2, double dRad) ; ICurveComposite* CurveFromFces( const FCEDEQUE& dqFce, int nStartInd = 0) ; bool SetNameAndInfo( int nId, int nGroup, int nProc, int nSide, const std::string& sDes, int nProcId) ; bool SetParams( int nId, const INTVECTOR& vnDPar, const DBLVECTOR& vdPar) ; diff --git a/BtlGeomProc.cpp b/BtlGeomProc.cpp index 634f652..96234fb 100644 --- a/BtlGeomProc.cpp +++ b/BtlGeomProc.cpp @@ -1991,43 +1991,47 @@ BtlGeom::AddDrill( int nGroup, int nProc, int nSide, const string& sDes, int nPr vtN = FromSpherical( 1, ANG_RIGHT - dAngVert, ANG_STRAIGHT + dAngHor) ; vtN.Rotate( Y_AX, ANG_RIGHT) ; } - } + } + // porto i dati in globale + Frame3d frRef = GetSideFrame( nSide) ; + ptP.ToGlob( frRef) ; + vtN.ToGlob( frRef) ; + // determino i punti iniziale e finale + Point3d ptStart = ptP ; + Point3d ptEnd = ptP - vtN * dDepth ; + // limito i punti, tenendo conto del raggio + if ( ! TrimSegmentWithBox( ptStart, ptEnd, dRad)) + return false ; + dDepth = ( ptStart - ptEnd) * vtN ; // creo la circonferenza PtrOwner pArc( CreateCurveArc()) ; if ( IsNull( pArc)) return false ; // assegno i dati - if ( ! pArc->Set( ptP, vtN, dRad)) + if ( ! pArc->Set( ptStart, vtN, dRad)) return false ; pArc->SetExtrusion( vtN) ; pArc->SetThickness( - dDepth) ; - // porto l'entitą in globale - Frame3d frRef = GetSideFrame( nSide) ; - pArc->ToGlob( frRef) ; - Vector3d vtNG = pArc->GetNormVersor() ; - // determino i punti iniziale e finale - Point3d ptStart = pArc->GetCenter() ; - Point3d ptEnd = ptStart - vtNG * dDepth ; - // verifico se inizio su faccia + // verifico se inizio su faccia (o fuori) int nStartFace = 0 ; double dSinStart = 0 ; for ( int i = BTL_SIDE_FRONT ; i <= BTL_SIDE_LEFT ; ++ i) { Plane3d plSide = GetSidePlane( i) ; - if ( PointInPlaneApprox( ptStart, plSide) && vtNG * plSide.GetVersN() > COS_ALMOST_PERP) { + if ( ( ptStart - ORIG) * plSide.GetVersN() - plSide.GetDist() > -EPS_SMALL && vtN * plSide.GetVersN() > COS_ALMOST_PERP) { nStartFace = i ; - dSinStart = sqrt( max( 0., 1 - vtNG * plSide.GetVersN())) ; + dSinStart = sqrt( max( 0., 1 - vtN * plSide.GetVersN())) ; break ; } } double dStartAgg = (( nStartFace == 0 || dSinStart < EPS_SMALL) ? 0 : dRad * dSinStart + LEN_EXTRUS_AGG) ; - // verifico se fine su faccia + // verifico se fine su faccia (o fuori) int nEndFace = 0 ; double dSinEnd = 0 ; for ( int i = BTL_SIDE_FRONT ; i <= BTL_SIDE_LEFT ; ++ i) { Plane3d plSide = GetSidePlane( i) ; - if ( PointInPlaneApprox( ptEnd, plSide) && - vtNG * plSide.GetVersN() > COS_ALMOST_PERP) { + if ( ( ptEnd - ORIG) * plSide.GetVersN() - plSide.GetDist() > -EPS_SMALL && - vtN * plSide.GetVersN() > COS_ALMOST_PERP) { nEndFace = i ; - dSinEnd = sqrt( max( 0., 1 + vtNG * plSide.GetVersN())) ; + dSinEnd = sqrt( max( 0., 1 + vtN * plSide.GetVersN())) ; break ; } } @@ -2038,18 +2042,18 @@ BtlGeom::AddDrill( int nGroup, int nProc, int nSide, const string& sDes, int nPr if ( ! pArc->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL) || ! pCompo->FromPolyLine( PL)) return false ; - pCompo->SetExtrusion( vtNG) ; + pCompo->SetExtrusion( vtN) ; // creo la superficie trimesh laterale del foro PtrOwner pStm( CreateSurfTriMesh()) ; - if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, - vtNG * ( dDepth + dStartAgg + dEndAgg))) + if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, - vtN * ( dDepth + dStartAgg + dEndAgg))) return false ; - pStm->Translate( vtNG * dStartAgg) ; + pStm->Translate( vtN * dStartAgg) ; // se chiuso, creo la superficie trimesh di fondo del foro if ( nEndFace == 0) { PtrOwner pStmBot( CreateSurfTriMesh()) ; if ( IsNull( pStmBot) || ! pStmBot->CreateByPointCurve( ptStart, PL)) return false ; - pStmBot->Translate( - vtNG * dDepth) ; + pStmBot->Translate( - vtN * dDepth) ; pStm->DoSewing( *pStmBot) ; } // eseguo trim con le facce della trave @@ -3257,7 +3261,7 @@ BtlGeom::AddSimpleScarf( int nGroup, int nProc, int nSide, const string& sDes, i Vector3d vtN = ( nGroup == 2 ? - X_AX : X_AX) ; // punti di riferimento Point3d ptP1( dStartX, 0, - dDepthRef) ; - Point3d ptP2( dStartX - vtN.x * dLength, 0, - GetSideHeight( nSide) + dDepthRef) ; + Point3d ptP2( dStartX - vtN.x * dLength, 0, - GetSideHeight( nSide) + dDepthOpp) ; // creo il primo poligono di taglio Polygon3d plyFace1 ; if ( ! CreatePolygonInBox( ptP1, vtN, nSide, plyFace1)) @@ -4347,6 +4351,30 @@ BtlGeom::TrimFlatCurveWithBox( ICurve* pCurve) return false ; } +//---------------------------------------------------------------------------- +bool +BtlGeom::TrimSegmentWithBox( Point3d& ptP1, Point3d& ptP2, double dRad) +{ + // eseguo trim con le facce della trave + for ( int i = BTL_SIDE_FRONT ; i <= BTL_SIDE_LEFT ; ++ i) { + // piano della faccia + Plane3d plFace = GetSidePlane( i) ; + // distanza con segno dei punti dal piano + double dDist1 = DistPointPlane( ptP1, plFace) ; + double dDist2 = DistPointPlane( ptP2, plFace) ; + // se entrambi esterni di pił del raggio, segmento da annullare + if ( dDist1 > dRad + EPS_SMALL && dDist2 > dRad + EPS_SMALL) + return false ; + // se primo esterno, devo spostare inizio + if ( dDist1 > EPS_SMALL) + ptP1 = Media( ptP1, ptP2, dDist1 / ( dDist1 + abs( dDist2))) ; + // se secondo esterno, devo spostare fine + else if ( dDist2 > EPS_SMALL) + ptP2 = Media( ptP2, ptP1, dDist2 / ( dDist2 + abs( dDist1))) ; + } + return true ; +} + //---------------------------------------------------------------------------- ICurveComposite* BtlGeom::CurveFromFces( const FCEDEQUE& dqFce, int nStartInd) diff --git a/EgtExchange.rc b/EgtExchange.rc index 80adb28..1adf597 100644 Binary files a/EgtExchange.rc and b/EgtExchange.rc differ