EgtGeomKernel 2.1e3 :

- aggiunta gestione punti notevoli per Zmap.
This commit is contained in:
Dario Sassi
2019-05-13 06:39:03 +00:00
parent b615b1748b
commit de0f4eb76d
3 changed files with 222 additions and 0 deletions
+219
View File
@@ -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,