//---------------------------------------------------------------------------- // EgalTech 2014-2014 //---------------------------------------------------------------------------- // File : SceneSnap.cpp Data : 09.10.14 Versione : 1.5j1 // Contenuto : Implementazione snap di punti trmite selezione. // // // // Modifiche : 09.10.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "Scene.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EgkGeoPoint3d.h" #include "/EgtDev/Include/EgkGeoVector3d.h" #include "/EgtDev/Include/EGkFrame3d.h" #include "/EgtDev/Include/EGkCurve.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkExtText.h" using namespace std ; //---------------------------------------------------------------------------- bool Scene::GetSelectedSnapPoint( int nSnap, const Point3d& ptWin, int nW, int nH, Point3d& ptSel) { // verifico siano state selezionate delle entità int nSel ; Select( ptWin, nW, nH, nSel) ; if ( nSel <= 0) return false ; // recupero le entità selezionate INTVECTOR nIds ; GetSelectedObjs( nIds) ; // cerco il punto estremo più vicino alla selezione bool bFound = false ; double dMinSqDist = INFINITO * INFINITO ; for ( size_t i = 0 ; i < nIds.size() ; ++ i) { // se non è entità geometrica const IGeoObj* pGObj ; if ( ( pGObj = m_pGeomDB->GetGeoObj( nIds[i])) == nullptr) continue ; // recupero riferimento dell'entità Frame3d frEnt ; if ( ! m_pGeomDB->GetGlobFrame( nIds[i], frEnt)) continue ; // se punto if ( pGObj->GetType() == GEO_PNT3D) { // recupero il geo-punto const IGeoPoint3d* pGP = GetGeoPoint3d( pGObj) ; // recupero il punto Point3d ptP = pGP->GetPoint() ; ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } // se vettore else if ( pGObj->GetType() == GEO_VECT3D) { // recupero il geo-vettore const IGeoVector3d* pGV = GetGeoVector3d( pGObj) ; // recupero il punto Point3d ptP = pGV->GetBase() ; ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } // se frame else if ( pGObj->GetType() == GEO_FRAME3D) { // recupero il geo-frame const IGeoFrame3d* pGF = GetGeoFrame3d( pGObj) ; // recupero il punto Point3d ptP = pGF->GetFrame().Orig() ; ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } // se curva else if ( ( pGObj->GetType() & GEO_CURVE) != 0) { // recupero la curva const ICurve* pCrv = GetCurve( m_pGeomDB->GetGeoObj( nIds[i])) ; // recupero il punto Point3d ptP ; switch ( nSnap) { case SP_END : // punto iniziale if ( pCrv->GetStartPoint( ptP)) { ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } // punto finale if ( pCrv->GetEndPoint( ptP)) { ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } break ; case SP_MID : if ( pCrv->GetMidPoint( ptP)) { ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } break ; case SP_CENTER : if ( pCrv->GetCenterPoint( ptP)) { ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } break ; case SP_NEAR : { // il punto di riferimento deriva da XY su viewport e Z da selezione Point3d ptRefWin( ptWin.x, ptWin.y, GetSelectedObjWinZ( int( i))) ; Point3d ptRef ; // lo porto da spazio grafico a spazio geometrico globale UnProject( ptRefWin, ptRef) ; // lo porto nel frame della curva ptRef.ToLoc( frEnt) ; // determino il punto più vicino della curva a questo int nFlag ; DistPointCurve dstPtCurve( ptRef, *pCrv) ; if ( dstPtCurve.GetMinDistPoint( 0, ptP, nFlag)) { ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } } break ; } } // se testo else if ( pGObj->GetType() == EXT_TEXT) { // recupero il testo const IExtText* pTxt = GetExtText( pGObj) ; // recupero il punto Point3d ptP ; switch ( nSnap) { case SP_END : // punto iniziale if ( pTxt->GetStartPoint( ptP)) { ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } // punto sopra iniziale if ( pTxt->GetOverStartPoint( ptP)) { ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } // punto finale if ( pTxt->GetEndPoint( ptP)) { ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } // punto sopra finale if ( pTxt->GetOverEndPoint( ptP)) { ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } break ; case SP_MID : // punto medio if ( pTxt->GetMidPoint( ptP)) { ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } break ; case SP_CENTER : // centro if ( pTxt->GetCenterPoint( ptP)) { ptP.ToGlob( frEnt) ; if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) { bFound = true ; ptSel = ptP ; } } break ; } } } return bFound ; } //---------------------------------------------------------------------------- bool Scene::VerifySnapPoint( const Point3d& ptP, const Point3d& ptWin, double& dMinSqDist) { // proietto il punto sulla viewport Point3d ptWinP ; Project( ptP, ptWinP) ; // confronto le distanze double dSqDist = SqDistXY( ptWin, ptWinP) ; if ( dSqDist < dMinSqDist) { dMinSqDist = dSqDist ; return true ; } return false ; }