fbe6c7232e
- migliorate GetPointFromSelect con superfici trimesh e FindSurfTMSnapPoint per ricerca triangolo/punto dell'oggetto inquadrato nel mirino.
547 lines
19 KiB
C++
547 lines
19 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2013-2014
|
|
//----------------------------------------------------------------------------
|
|
// File : SceneSelect.cpp Data : 26.11.14 Versione : 1.5k5
|
|
// Contenuto : Implementazione della selezione nella scena.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 26.11.14 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "Scene.h"
|
|
#include "GraphObjs.h"
|
|
#include "ObjEGrGraphics.h"
|
|
#include "DllMain.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/EGkSurfTriMesh.h"
|
|
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
|
|
#include "/EgtDev/Include/EGkSurfBezier.h"
|
|
#include "/EgtDev/Include/EGkExtText.h"
|
|
#include "/EgtDev/Include/EGkExtDimension.h"
|
|
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
|
#include "/EgtDev/Include/EGkGdbConst.h"
|
|
#include "/EgtDev/Include/EGkGeomDB.h"
|
|
#include <algorithm>
|
|
|
|
using namespace std ;
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
CompareSelRec( const void* pSr1, const void* pSr2)
|
|
{
|
|
if ( ((SelRec*)pSr1)->nZmin > ((SelRec*)pSr2)->nZmin)
|
|
return 1 ;
|
|
else if ( ((SelRec*)pSr1)->nZmin < ((SelRec*)pSr2)->nZmin)
|
|
return - 1 ;
|
|
else {
|
|
if ( ((SelRec*)pSr1)->nId > ((SelRec*)pSr2)->nId)
|
|
return 1 ;
|
|
else if ( ((SelRec*)pSr1)->nId < ((SelRec*)pSr2)->nId)
|
|
return - 1 ;
|
|
else
|
|
return 0 ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Scene::Select( const Point3d& ptSelCenter, int nW, int nH, int& nSel)
|
|
{
|
|
// inizializzo selezione
|
|
m_bSelect = true ;
|
|
m_ptSelCent = ptSelCenter ;
|
|
m_nSelW = abs( nW) ;
|
|
m_nSelH = abs( nH) ;
|
|
m_nSelNbr = 0 ;
|
|
|
|
// se una delle due dimensioni è nulla, non posso selezionare alcunché
|
|
if ( m_nSelW == 0 || m_nSelH == 0) {
|
|
m_bSelect = false ;
|
|
nSel = m_nSelNbr ;
|
|
return true ;
|
|
}
|
|
|
|
// sfondo e Zbuffer non interessano
|
|
|
|
// imposto la camera, riducendo la viewport all'area di selezione
|
|
if ( ! Prepare()) {
|
|
m_bSelect = false ;
|
|
nSel = m_nSelNbr ;
|
|
return false ;
|
|
}
|
|
|
|
// imposto modalità di selezione
|
|
glSelectBuffer( SIZE_SEL_BUF, (GLuint*)m_nSelBuff) ;
|
|
glRenderMode( GL_SELECT) ;
|
|
|
|
// inizializzo stack dei nomi
|
|
glInitNames() ;
|
|
glPushName( 0) ;
|
|
|
|
// eseguo disegno
|
|
// disabilito illuminazione
|
|
glDisable( GL_LIGHTING) ;
|
|
// non imposto glPolygonMode secondo il tipo di rendering perchè ignorato in selezione
|
|
// disegno le geometrie del DB in una sola passata
|
|
DrawGroup( GDB_ID_ROOT, 1, MdStMkCol( GDB_MD_STD, GDB_ST_ON, GDB_MK_OFF, m_colDef)) ;
|
|
|
|
// pulisco stack nomi
|
|
glPopName() ;
|
|
|
|
// chiudo modalità selezione, recupero buffer ripristino le matrici di OpenGL
|
|
m_nSelNbr = glRenderMode( GL_RENDER) ;
|
|
if ( m_nSelNbr < 0)
|
|
m_nSelNbr = DIM_SEL_BUF ;
|
|
m_bSelect = false ;
|
|
Prepare() ;
|
|
|
|
// riordino il buffer di selezione secondo la Zdepth minima crescente
|
|
qsort( m_nSelBuff, m_nSelNbr, sizeof( SelRec), CompareSelRec) ;
|
|
|
|
nSel = m_nSelNbr ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Scene::SetObjFilterForSelect( bool bZerodim, bool bCurve, bool bSurf, bool bVolume, bool bExtra)
|
|
{
|
|
m_nObjFilterForSelect = 0 ;
|
|
if ( bZerodim)
|
|
m_nObjFilterForSelect |= GEO_ZERODIM ;
|
|
if ( bCurve)
|
|
m_nObjFilterForSelect |= GEO_CURVE ;
|
|
if ( bSurf)
|
|
m_nObjFilterForSelect |= GEO_SURF ;
|
|
if ( bVolume)
|
|
m_nObjFilterForSelect |= GEO_VOLUME ;
|
|
if ( bExtra)
|
|
m_nObjFilterForSelect |= GEO_EXTRA ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Scene::GetSelectedObjs( INTVECTOR& nIds) const
|
|
{
|
|
// inizializzo vettore Id
|
|
nIds.clear() ;
|
|
try { nIds.reserve( m_nSelNbr) ; }
|
|
catch(...) { return false ; }
|
|
// inserisco l'Id degli oggetti selezionati
|
|
for ( int i = 0 ; i < m_nSelNbr ; ++ i)
|
|
nIds.push_back( m_nSelBuff[i].nId) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
Scene::GetFirstSelectedObj( void)
|
|
{
|
|
m_nSelCurr = - 1 ;
|
|
return GetNextSelectedObj() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
Scene::GetNextSelectedObj( void)
|
|
{
|
|
// fuori dal range
|
|
m_nSelCurr ++ ;
|
|
if ( m_nSelCurr < 0 || m_nSelCurr >= m_nSelNbr)
|
|
return GDB_ID_NULL ;
|
|
return m_nSelBuff[m_nSelCurr].nId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double
|
|
Scene::GetSelectedObjWinZ( int nSel) const
|
|
{
|
|
if ( nSel < 0)
|
|
nSel = m_nSelCurr ;
|
|
if ( nSel < 0 || nSel >= m_nSelNbr)
|
|
return 0.5 ;
|
|
return 0.5 * ( double( m_nSelBuff[nSel].nZmin) + double( m_nSelBuff[nSel].nZmax)) / UINT_MAX ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double
|
|
Scene::GetSelectedObjMinWinZ( int nSel) const
|
|
{
|
|
if ( nSel < 0)
|
|
nSel = m_nSelCurr ;
|
|
if ( nSel < 0 || nSel >= m_nSelNbr)
|
|
return 0.5 ;
|
|
return ( double( m_nSelBuff[nSel].nZmin)) / UINT_MAX ;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------------------*/
|
|
bool
|
|
Scene::UnselectableAdd( int nId)
|
|
{
|
|
// non si ammettono radice e id negativi
|
|
if ( nId <= GDB_ID_ROOT)
|
|
return false ;
|
|
// verifico se già presente
|
|
if ( binary_search( m_Unsel.begin(), m_Unsel.end(), nId))
|
|
return true ;
|
|
// inserisco l'elemento
|
|
m_Unsel.push_back( nId) ;
|
|
// ordino in senso crescente
|
|
stable_sort( m_Unsel.begin(), m_Unsel.end()) ;
|
|
return true ;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------------------*/
|
|
bool
|
|
Scene::UnselectableRemove( int nId)
|
|
{
|
|
// non si ammettono radice e id negativi
|
|
if ( nId <= GDB_ID_ROOT)
|
|
return false ;
|
|
// cerco l'elemento
|
|
INTVECTOR::iterator Iter = find( m_Unsel.begin(), m_Unsel.end(), nId) ;
|
|
if ( Iter == m_Unsel.end())
|
|
return true ;
|
|
m_Unsel.erase( Iter) ;
|
|
return true ;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------------------*/
|
|
bool
|
|
Scene::UnselectableClearAll( void)
|
|
{
|
|
// cancello tutto
|
|
m_Unsel.clear() ;
|
|
return true ;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------------------*/
|
|
bool
|
|
Scene::UnselectableFind( int nId)
|
|
{
|
|
// eseguo ricerca su vettore ordinato in senso crescente
|
|
return binary_search( m_Unsel.begin(), m_Unsel.end(), nId) ;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------------------*/
|
|
bool
|
|
Scene::GetPointFromSelect( int nSelId, const Point3d& ptView, Point3d& ptSel, int& nAux)
|
|
{
|
|
// recupera il punto di mira proiettato sull'oggetto appena selezionato
|
|
// (va eseguito subito dopo la Select da cui si è derivato l'Id)
|
|
// è simile a FindSelectedSnapPoint
|
|
|
|
// verifico parametri di ritorno
|
|
if ( &ptSel == nullptr || &nAux == nullptr)
|
|
return false ;
|
|
|
|
// rendo corrente l'entità selezionata
|
|
bool bFound = false ;
|
|
for ( int nId = GetFirstSelectedObj() ; nId != GDB_ID_NULL ; nId = GetNextSelectedObj()) {
|
|
if ( nId == nSelId) {
|
|
bFound = true ;
|
|
break ;
|
|
}
|
|
}
|
|
if ( ! bFound)
|
|
return false ;
|
|
|
|
// verifico sia entità geometrica
|
|
const IGeoObj* pGObj ;
|
|
if ( ( pGObj = m_pGeomDB->GetGeoObj( nSelId)) == nullptr)
|
|
return false ;
|
|
|
|
// recupero riferimento dell'entità
|
|
Frame3d frEnt ;
|
|
if ( ! m_pGeomDB->GetGlobFrame( nSelId, frEnt))
|
|
return false ;
|
|
|
|
// inizializzo indice ausiliario (Id del sotto-oggetto : curva semplice o triangolo)
|
|
nAux = 0 ;
|
|
// se punto
|
|
if ( pGObj->GetType() == GEO_PNT3D) {
|
|
// recupero il geo-punto
|
|
const IGeoPoint3d* pGP = GetGeoPoint3d( pGObj) ;
|
|
// recupero il punto
|
|
ptSel = GetToGlob( pGP->GetPoint(), frEnt) ;
|
|
}
|
|
// se vettore
|
|
else if ( pGObj->GetType() == GEO_VECT3D) {
|
|
// recupero il geo-vettore
|
|
const IGeoVector3d* pGV = GetGeoVector3d( pGObj) ;
|
|
// recupero il punto
|
|
ptSel = GetToGlob( pGV->GetBase(), frEnt) ;
|
|
}
|
|
// se frame
|
|
else if ( pGObj->GetType() == GEO_FRAME3D) {
|
|
// recupero il geo-frame
|
|
const IGeoFrame3d* pGF = GetGeoFrame3d( pGObj) ;
|
|
// recupero il punto
|
|
ptSel = GetToGlob( pGF->GetFrame().Orig(), frEnt) ;
|
|
}
|
|
// se curva
|
|
else if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
|
|
// recupero la curva
|
|
const ICurve* pCrv = GetCurve( pGObj) ;
|
|
// il punto di riferimento deriva da XY su viewport e Z da selezione
|
|
Point3d ptWinZ( ptView.x, ptView.y, GetSelectedObjWinZ()) ;
|
|
// lo porto da spazio grafico a spazio geometrico globale
|
|
Point3d ptRef ;
|
|
UnProject( ptWinZ, ptRef) ;
|
|
// lo porto nel frame della curva
|
|
ptRef.ToLoc( frEnt) ;
|
|
// determino il punto più vicino della curva a questo
|
|
double dMinSqDist = INFINITO * INFINITO ;
|
|
MinDistPCInfo mdInfo ;
|
|
DistPointCurve dstPtCurve( ptRef, *pCrv) ;
|
|
if ( dstPtCurve.GetMinDistInfo( 0, mdInfo)) {
|
|
Point3d ptP = GetToGlob( mdInfo.ptQ, frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist)) {
|
|
ptSel = ptP ;
|
|
nAux = int( mdInfo.dPar) ;
|
|
}
|
|
}
|
|
// eventuale verifica dell'estruso
|
|
double dTh ;
|
|
Vector3d vtExtr ;
|
|
if ( pCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall() &&
|
|
pCrv->GetThickness( dTh) && abs( dTh) > EPS_SMALL) {
|
|
vtExtr *= dTh ;
|
|
vtExtr.ToGlob( frEnt) ;
|
|
// correggo il punto di riferimento del contrario dell'estrusione
|
|
Vector3d vtTemp = GetToLoc( vtExtr, frEnt) ;
|
|
// determino il punto più vicino della curva a questo
|
|
MinDistPCInfo mdInfo ;
|
|
DistPointCurve dstPtCurve( ptRef - vtTemp, *pCrv) ;
|
|
if ( dstPtCurve.GetMinDistInfo( 0, mdInfo)) {
|
|
Point3d ptP = GetToGlob( mdInfo.ptQ, frEnt) ;
|
|
ptP += vtExtr ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist)) {
|
|
ptSel = ptP ;
|
|
nAux = int( mdInfo.dPar) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// se superficie trimesh
|
|
else if ( pGObj->GetType() == SRF_TRIMESH) {
|
|
// recupero la superficie
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGObj) ;
|
|
// il punto di riferimento deriva da XY su viewport e Z da selezione
|
|
Point3d ptWinZ( ptView.x, ptView.y, GetSelectedObjWinZ()) ;
|
|
// lo porto da spazio grafico a spazio geometrico globale
|
|
Point3d ptRef ;
|
|
UnProject( ptWinZ, ptRef) ;
|
|
// lo porto nel frame della superficie
|
|
ptRef.ToLoc( frEnt) ;
|
|
// recupero la direzione di mira e la porto nel riferimento della superficie
|
|
Vector3d vtDir = GetToLoc( -m_vtDirCamera, frEnt) ;
|
|
// recupero il raggio del box di ingombro
|
|
double dBlRad = 1000 ;
|
|
const ObjEGrGraphics* pGraphics = GetObjEGrGraphics( pStm) ;
|
|
if ( pGraphics != nullptr) {
|
|
BBox3d b3Loc ;
|
|
if ( pGraphics->GetLocalBBox( b3Loc))
|
|
b3Loc.GetRadius( dBlRad) ;
|
|
}
|
|
// punto davanti all'oggetto lungo il raggio di mira
|
|
Point3d ptMir = ptRef - vtDir * 2 * dBlRad ;
|
|
double dLenMir = 4 * dBlRad ;
|
|
// cerco i triangoli intersecati dalla linea di mira
|
|
ILSIVECTOR vInfo ;
|
|
if ( ! IntersLineSurfTm( ptMir, vtDir, dLenMir, *pStm, vInfo))
|
|
return false ;
|
|
// se non trovato alcunchè, cerco le linee che partono dagli angoli e dai punti medi dei lati del rettangolo di mira
|
|
VCT3DVECTOR vVtWind = { {0.51, 0.51, 0}, {0, 0.51, 0}, {-0.51, 0.51, 0}, {-0.51, 0, 0},
|
|
{-0.51, -0.51, 0}, {0, -0.51, 0}, {0.51, -0.51, 0}, {0.51, 0, 0},
|
|
{0.25, 0.51, 0}, {-0.25, 0.51, 0}, {-0.51, 0.25, 0}, {-0.51, -0.25, 0},
|
|
{-0.25, -0.51, 0}, {0.25, -0.51, 0}, {0.51, -0.25, 0}, {0.51, 0.25, 0}} ;
|
|
for ( int i = 0 ; i < int( vVtWind.size()) && vInfo.empty() ; ++ i) {
|
|
// determino punto su vertice del rettangolo di selezione
|
|
Point3d ptWinZ2 = ptWinZ + vVtWind[i].x * m_nSelH * X_AX + vVtWind[i].y * m_nSelW * Y_AX ;
|
|
// ne ricavo punto di mira
|
|
Point3d ptMir2 ;
|
|
if ( ! UnProject( ptWinZ2, ptMir2))
|
|
return false ;
|
|
ptMir2.ToLoc( frEnt) ;
|
|
ptMir2 -= vtDir * 2 * dBlRad ;
|
|
// interseco con la superficie
|
|
if ( ! IntersLineSurfTm( ptMir2, vtDir, dLenMir, *pStm, vInfo))
|
|
return false ;
|
|
}
|
|
if ( vInfo.empty())
|
|
return false ;
|
|
// recupero il primo punto
|
|
ptSel = GetToGlob( vInfo[0].ptI, frEnt) ;
|
|
nAux = vInfo[0].nT ;
|
|
}
|
|
// se regione
|
|
else if ( pGObj->GetType() == SRF_FLATRGN) {
|
|
// recupero la regione
|
|
const ISurfFlatRegion* pReg = GetSurfFlatRegion( pGObj) ;
|
|
// il punto di riferimento deriva da XY su viewport e Z da selezione
|
|
Point3d ptWinZ( ptView.x, ptView.y, GetSelectedObjWinZ()) ;
|
|
// lo porto da spazio grafico a spazio geometrico globale
|
|
Point3d ptRef ;
|
|
UnProject( ptWinZ, ptRef) ;
|
|
// lo porto nel frame della regione
|
|
ptRef.ToLoc( frEnt) ;
|
|
// recupero la direzione di mira e la porto nel riferimento della regione
|
|
Vector3d vtDir = GetToLoc( -m_vtDirCamera, frEnt) ;
|
|
// recupero il piano della regione
|
|
Plane3d plReg ;
|
|
plReg.Set( pReg->GetPlanePoint(), pReg->GetNormVersor()) ;
|
|
// interseco la linea di mira con il piano della regione
|
|
Point3d ptInt ;
|
|
if ( IntersLinePlane( ptRef, vtDir, INFINITO, plReg, ptInt, false) != ILPT_YES)
|
|
return false ;
|
|
// assegno il punto
|
|
ptSel = GetToGlob( ptInt, frEnt) ;
|
|
// determino il chunk
|
|
nAux = 0 ;
|
|
if ( pReg->GetChunkCount() > 1) {
|
|
// verifico a quale contorno esterno di chunk è più vicino (potrebbe essere appena fuori dal bordo il centro del mirino)
|
|
double dMinSqDist = INFINITO * INFINITO ;
|
|
for ( int nC = 0 ; nC < pReg->GetChunkCount() ; ++ nC) {
|
|
PtrOwner<ICurve> pCrv( pReg->GetLoop( nC, 0)) ;
|
|
if ( IsNull( pCrv))
|
|
return false ;
|
|
double dSqDist ;
|
|
if ( DistPointCurve( ptInt, *pCrv).GetSqDist( dSqDist) && dSqDist < dMinSqDist) {
|
|
nAux = nC ;
|
|
dMinSqDist = dSqDist ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// se superficie di Bezier
|
|
else if ( pGObj->GetType() == SRF_BEZIER) {
|
|
// recupero la superficie
|
|
const ISurfBezier* pSbz = GetSurfBezier( pGObj) ;
|
|
const ISurfTriMesh* pStm = pSbz->GetAuxSurf() ;
|
|
// il punto di riferimento deriva da XY su viewport e Z da selezione
|
|
Point3d ptWinZ( ptView.x, ptView.y, GetSelectedObjWinZ()) ;
|
|
// lo porto da spazio grafico a spazio geometrico globale
|
|
Point3d ptRef ;
|
|
UnProject( ptWinZ, ptRef) ;
|
|
// lo porto nel frame della superficie
|
|
ptRef.ToLoc( frEnt) ;
|
|
// recupero la direzione di mira e la porto nel riferimento della superficie
|
|
Vector3d vtDir = GetToLoc( -m_vtDirCamera, frEnt) ;
|
|
// recupero il raggio del box di ingombro
|
|
double dBlRad = 1000 ;
|
|
const ObjEGrGraphics* pGraphics = GetObjEGrGraphics( pStm) ;
|
|
if ( pGraphics != nullptr) {
|
|
BBox3d b3Loc ;
|
|
if ( pGraphics->GetLocalBBox( b3Loc))
|
|
b3Loc.GetRadius( dBlRad) ;
|
|
}
|
|
// punto davanti all'oggetto lungo il raggio di mira
|
|
Point3d ptMir = ptRef - vtDir * 2 * dBlRad ;
|
|
double dLenMir = 4 * dBlRad ;
|
|
// cerco i triangoli intersecati dalla linea di mira
|
|
ILSIVECTOR vInfo ;
|
|
if ( ! IntersLineSurfTm( ptMir, vtDir, dLenMir, *pStm, vInfo) || vInfo.size() == 0)
|
|
return false ;
|
|
// recupero il primo punto
|
|
ptSel = GetToGlob( vInfo[0].ptI, frEnt) ;
|
|
nAux = 0 ;
|
|
}
|
|
// se testo
|
|
else if ( pGObj->GetType() == EXT_TEXT) {
|
|
// recupero il testo
|
|
const IExtText* pTxt = GetExtText( pGObj) ;
|
|
// cerco il punto
|
|
double dMinSqDist = INFINITO * INFINITO ;
|
|
Point3d ptP ;
|
|
// punto iniziale
|
|
if ( pTxt->GetStartPoint( ptP)) {
|
|
ptP.ToGlob( frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
}
|
|
// punto sopra iniziale
|
|
if ( pTxt->GetOverStartPoint( ptP)) {
|
|
ptP.ToGlob( frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
}
|
|
// punto finale
|
|
if ( pTxt->GetEndPoint( ptP)) {
|
|
ptP.ToGlob( frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
}
|
|
// punto sopra finale
|
|
if ( pTxt->GetOverEndPoint( ptP)) {
|
|
ptP.ToGlob( frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
}
|
|
// punto medio
|
|
if ( pTxt->GetMidPoint( ptP)) {
|
|
ptP.ToGlob( frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
}
|
|
// centro
|
|
if ( pTxt->GetCenterPoint( ptP)) {
|
|
ptP.ToGlob( frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
}
|
|
}
|
|
// se quotatura
|
|
else if ( pGObj->GetType() == EXT_DIMENSION) {
|
|
// recupero la quotatura
|
|
const IExtDimension* pDim = GetExtDimension( pGObj) ;
|
|
// verifico sia valida
|
|
if ( pDim->IsValid()) {
|
|
// cerco il punto
|
|
double dMinSqDist = INFINITO * INFINITO ;
|
|
Point3d ptP ;
|
|
// punto iniziale
|
|
ptP = GetToGlob( pDim->GetStart(), frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
// punto sopra iniziale
|
|
ptP = GetToGlob( pDim->GetOverStart(), frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
// punto finale
|
|
ptP = GetToGlob( pDim->GetEnd(), frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
// punto sopra finale
|
|
ptP = GetToGlob( pDim->GetOverEnd(), frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
// punto medio
|
|
if ( pDim->GetMidPoint( ptP)) {
|
|
ptP.ToGlob( frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
}
|
|
// centro
|
|
if ( pDim->GetCenterPoint( ptP)) {
|
|
ptP.ToGlob( frEnt) ;
|
|
if ( VerifySnapPoint( ptP, ptView, dMinSqDist))
|
|
ptSel = ptP ;
|
|
}
|
|
}
|
|
}
|
|
return true ;
|
|
}
|