EgtGeomKernel 2.1e3 :
- aggiunta gestione punti notevoli per Zmap.
This commit is contained in:
+219
@@ -25,6 +25,7 @@
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
|
||||
#include "/EgtDev/Include/EGkVolZmap.h"
|
||||
#include "/EgtDev/Include/EGkExtText.h"
|
||||
#include "/EgtDev/Include/EgkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
@@ -338,6 +339,14 @@ Scene::FindSelectedSnapPoint( int nSnap, const Point3d& ptWin, int nW, int nH)
|
||||
if ( FindSurfFRSnapPoint( nSnap, ptWin, nId, frEnt, pReg, dMinSqDist))
|
||||
bFound = true ;
|
||||
}
|
||||
// se solido Zmap
|
||||
else if ( pGObj->GetType() == VOL_ZMAP) {
|
||||
// recupero il solido
|
||||
const IVolZmap* pVzm = GetVolZmap( pGObj) ;
|
||||
// verifico i punti notevoli del solido
|
||||
if ( FindVolZmapSnapPoint( nSnap, ptWin, nId, frEnt, pVzm, dMinSqDist))
|
||||
bFound = true ;
|
||||
}
|
||||
// se testo
|
||||
else if ( pGObj->GetType() == EXT_TEXT) {
|
||||
// recupero il testo
|
||||
@@ -902,6 +911,216 @@ Scene::FindSurfFRSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram
|
||||
return bFound ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Scene::FindVolZmapSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Frame3d& frEnt,
|
||||
const IVolZmap* pVzm, double& dMinSqDist)
|
||||
{
|
||||
// il punto di riferimento deriva da XY su viewport e Z minima (più vicina a osservatore) da selezione
|
||||
Point3d ptWinZ( ptWin.x, ptWin.y, GetSelectedObjMinWinZ()) ;
|
||||
// punto di riferimento nello spazio geometrico 3d
|
||||
Point3d ptRef ;
|
||||
if ( ! UnProject( ptWinZ, ptRef))
|
||||
return false ;
|
||||
// porto il punto nel riferimento della superficie
|
||||
ptRef.ToLoc( frEnt) ;
|
||||
// recupero la direzione di mira e la porto nel riferimento della superficie
|
||||
Vector3d vtDir = - m_vtDirCamera ;
|
||||
vtDir.ToLoc( frEnt) ;
|
||||
// recupero il raggio del box di ingombro
|
||||
double dBlRad = 1000 ;
|
||||
const ObjEGrGraphics* pGraphics = GetObjEGrGraphics( pVzm) ;
|
||||
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 ;
|
||||
|
||||
// determino se oggetto trasparente
|
||||
Color cCol ;
|
||||
bool bAlpha = ( m_pGeomDB->GetCalcMaterial( nId, cCol) && cCol.GetIntAlpha() <= ALPHA_LIM) ;
|
||||
|
||||
// se richiesto il centro di gravità (baricentro, centroide)
|
||||
if ( nSnap == SP_CENTROID) {
|
||||
Point3d ptP ;
|
||||
bool bFound = false ;
|
||||
BBox3d b3Loc ;
|
||||
if ( pVzm->GetLocalBBox( b3Loc) && b3Loc.GetCenter( ptP)) {
|
||||
// il punto di confronto è quello sulla linea di mira a minima distanza dal vertice
|
||||
Point3d ptCfr = ptRef + (( ptP - ptRef) * vtDir) * vtDir ;
|
||||
// determino la distanza e la confronto con il minimo
|
||||
double dSqDist = SqDist( ptP, ptCfr) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
bFound = true ;
|
||||
dMinSqDist = dSqDist ;
|
||||
m_nLastSnapId = nId ;
|
||||
m_ptLastSnapPnt = ptP ;
|
||||
m_ptLastSnapPnt.ToGlob( frEnt) ;
|
||||
m_bLastSnapDirOk = false ;
|
||||
}
|
||||
}
|
||||
// se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive
|
||||
if ( bFound && ! ( bAlpha || m_nShowMode == SM_WIREFRAME))
|
||||
dMinSqDist = 0 ;
|
||||
return bFound ;
|
||||
}
|
||||
|
||||
// cerco i triangoli intersecati dalla linea di mira
|
||||
ILZIVECTOR vInfo ;
|
||||
if ( ! pVzm->GetLineIntersection( ptMir, vtDir, vInfo))
|
||||
return false ;
|
||||
// se non trovato alcunchè, cerco le linee che partono dagli angoli del rettangolo di mira
|
||||
Vector3d vtWinD( -1, -1, 0) ;
|
||||
for ( int i = 0 ; i < 4 && vInfo.size() == 0 ; ++ i) {
|
||||
// determino punto su vertice del rettangolo di selezione
|
||||
Point3d ptWinZ2 = ptWinZ + vtWinD.x * m_nSelH * X_AX + vtWinD.y * m_nSelW * Y_AX ;
|
||||
vtWinD.Rotate( Z_AX, 0, 1) ;
|
||||
// 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 ( ! pVzm->GetLineIntersection( ptMir2, vtDir, vInfo))
|
||||
return false ;
|
||||
}
|
||||
if ( vInfo.size() == 0)
|
||||
return false ;
|
||||
|
||||
// elaborazione a seconda del tipo di snap
|
||||
bool bFound = false ;
|
||||
switch ( nSnap) {
|
||||
case SP_END :
|
||||
{
|
||||
// con wireframe devo provare tutti i triangoli intersecati, con shading e hiddenline solo il primo
|
||||
int nTtot = (( bAlpha || m_nShowMode == SM_WIREFRAME) ? int( vInfo.size()) : 1) ;
|
||||
for ( int i = 0 ; i < nTtot ; ++ i) {
|
||||
// punto di intersezione
|
||||
Point3d ptInt = vInfo[i].ptI ;
|
||||
// triangolo
|
||||
Triangle3d& trTria = vInfo[i].trTria ;
|
||||
// punto finale più vicino
|
||||
Point3d ptEnd = trTria.GetP( 0) ;
|
||||
if ( SqDist( trTria.GetP( 1), ptInt) < SqDist( ptEnd, ptInt))
|
||||
ptEnd = trTria.GetP( 1) ;
|
||||
if ( SqDist( trTria.GetP( 2), ptInt) < SqDist( ptEnd, ptInt))
|
||||
ptEnd = trTria.GetP( 2) ;
|
||||
Vector3d vtN = trTria.GetN() ;
|
||||
// il punto di confronto è quello sulla linea di mira a minima distanza dal vertice
|
||||
Point3d ptCfr = ptRef + (( ptEnd - ptRef) * vtDir) * vtDir ;
|
||||
// determino la distanza e la confronto con il minimo
|
||||
double dSqDist = SqDist( ptEnd, ptCfr) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
bFound = true ;
|
||||
dMinSqDist = dSqDist ;
|
||||
m_nLastSnapId = nId ;
|
||||
m_ptLastSnapPnt = ptEnd ;
|
||||
m_ptLastSnapPnt.ToGlob( frEnt) ;
|
||||
m_bLastSnapDirOk = true ;
|
||||
m_vtLastSnapDir = vtN ;
|
||||
m_vtLastSnapDir.ToGlob( frEnt) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
break ;
|
||||
case SP_MID :
|
||||
{
|
||||
// con wireframe devo provare tutti i triangoli intersecati, con shading e hiddenline solo il primo
|
||||
int nTtot = (( bAlpha || m_nShowMode == SM_WIREFRAME) ? int( vInfo.size()) : 1) ;
|
||||
for ( int i = 0 ; i < nTtot ; ++ i) {
|
||||
// punto di intersezione
|
||||
Point3d ptInt = vInfo[i].ptI ;
|
||||
// triangolo
|
||||
Triangle3d& trTria = vInfo[i].trTria ;
|
||||
// punto medio più vicino
|
||||
Point3d ptMid = Media( trTria.GetP( 0), trTria.GetP( 1)) ;
|
||||
Point3d ptMid2 = Media( trTria.GetP( 1), trTria.GetP( 2)) ;
|
||||
if ( SqDist( ptMid2, ptInt) < SqDist( ptMid, ptInt))
|
||||
ptMid = ptMid2 ;
|
||||
Point3d ptMid3 = Media( trTria.GetP( 2), trTria.GetP( 0)) ;
|
||||
if ( SqDist( ptMid3, ptInt) < SqDist( ptMid, ptInt))
|
||||
ptMid = ptMid3 ;
|
||||
Vector3d vtN = trTria.GetN() ;
|
||||
// il punto di confronto è quello sulla linea di mira a minima distanza dal punto medio
|
||||
Point3d ptCfr = ptRef + (( ptMid - ptRef) * vtDir) * vtDir ;
|
||||
// determino la distanza e la confronto con il minimo
|
||||
double dSqDist = SqDist( ptMid, ptCfr) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
bFound = true ;
|
||||
dMinSqDist = dSqDist ;
|
||||
m_nLastSnapId = nId ;
|
||||
m_ptLastSnapPnt = ptMid ;
|
||||
m_ptLastSnapPnt.ToGlob( frEnt) ;
|
||||
m_bLastSnapDirOk = true ;
|
||||
m_vtLastSnapDir = vtN ;
|
||||
m_vtLastSnapDir.ToGlob( frEnt) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
break ;
|
||||
case SP_CENTER :
|
||||
{
|
||||
// con wireframe devo provare tutti i triangoli intersecati, con shading e hiddenline solo il primo
|
||||
int nTtot = (( bAlpha || m_nShowMode == SM_WIREFRAME) ? int( vInfo.size()) : 1) ;
|
||||
for ( int i = 0 ; i < nTtot ; ++ i) {
|
||||
// triangolo
|
||||
Triangle3d& trTria = vInfo[i].trTria ;
|
||||
// centro più vicino
|
||||
Point3d ptCen = trTria.GetCentroid() ;
|
||||
Vector3d vtN = trTria.GetN() ;
|
||||
// il punto di confronto è quello sulla linea di mira a minima distanza dal centro
|
||||
Point3d ptCfr = ptRef + (( ptCen - ptRef) * vtDir) * vtDir ;
|
||||
// determino la distanza e la confronto con il minimo
|
||||
double dSqDist = SqDist( ptCen, ptCfr) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
bFound = true ;
|
||||
dMinSqDist = dSqDist ;
|
||||
m_nLastSnapId = nId ;
|
||||
m_ptLastSnapPnt = ptCen ;
|
||||
m_ptLastSnapPnt.ToGlob( frEnt) ;
|
||||
m_bLastSnapDirOk = true ;
|
||||
m_vtLastSnapDir = vtN ;
|
||||
m_vtLastSnapDir.ToGlob( frEnt) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
break ;
|
||||
case SP_NEAR :
|
||||
case SP_TANG :
|
||||
case SP_PERP :
|
||||
case SP_MINDIST :
|
||||
// considero solo il primo triangolo intersecato
|
||||
// la distanza è nulla e la confronto con il minimo
|
||||
if ( 0 < dMinSqDist) {
|
||||
bFound = true ;
|
||||
dMinSqDist = 0 ;
|
||||
m_nLastSnapId = nId ;
|
||||
// punto
|
||||
Point3d ptInt = vInfo[0].ptI ;
|
||||
m_ptLastSnapPnt = ptInt ;
|
||||
m_ptLastSnapPnt.ToGlob( frEnt) ;
|
||||
// direzione
|
||||
Vector3d vtNorm = vInfo[0].trTria.GetN() ;
|
||||
m_bLastSnapDirOk = true ;
|
||||
m_vtLastSnapDir = vtNorm ;
|
||||
m_vtLastSnapDir.ToGlob( frEnt) ;
|
||||
}
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
|
||||
// se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive
|
||||
if ( bFound && ! ( bAlpha || m_nShowMode == SM_WIREFRAME))
|
||||
dMinSqDist = 0 ;
|
||||
|
||||
return bFound ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Scene::FindTextSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Frame3d& frEnt,
|
||||
|
||||
Reference in New Issue
Block a user