1941 lines
76 KiB
C++
1941 lines
76 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2020-2020
|
|
//----------------------------------------------------------------------------
|
|
// File : EXE_GeoSnap.cpp Data : 23.03.20 Versione : 2.2c3
|
|
// Contenuto : Funzioni di interrogazione di superfici del DBG per EXE.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 23.03.20 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "EXE.h"
|
|
#include "EXE_Const.h"
|
|
#include "EXE_Macro.h"
|
|
#include "AuxTools.h"
|
|
#include "GeoTools.h"
|
|
#include "/EgtDev/Include/EXeExecutor.h"
|
|
#include "/EgtDev/Include/EXeConst.h"
|
|
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
|
#include "/EgtDev/Include/EGkGeoVector3d.h"
|
|
#include "/EgtDev/Include/EGkCurveLine.h"
|
|
#include "/EgtDev/Include/EGkCurveBezier.h"
|
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkCurveLocal.h"
|
|
#include "/EgtDev/Include/EGkSurf.h"
|
|
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
|
|
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
|
#include "/EgtDev/Include/EGkSurfBezier.h"
|
|
#include "/EgtDev/Include/EGkDistPointSurfFr.h"
|
|
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
|
#include "/EgtDev/Include/EGkIntersCurves.h"
|
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
|
#include "/EgtDev/Include/EGkCAvSilhouetteSurfTm.h"
|
|
#include "/EgtDev/Include/EGkCalcPocketing.h"
|
|
#include "/EgtDev/Include/EGkPolygonElevation.h"
|
|
#include "/EgtDev/Include/EGkSurfLocal.h"
|
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfArea( int nId, double& dArea)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie
|
|
ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( nId)) ;
|
|
// ne restituisco l'area
|
|
return ( pSurf != nullptr && pSurf->GetArea( dArea)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfIsClosed( int nId)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie
|
|
ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( nId)) ;
|
|
// verifico se è superficie chiusa
|
|
return ( pSurf != nullptr && pSurf->IsClosed()) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfVolume( int nId, double& dVol)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie
|
|
ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( nId)) ;
|
|
// ne restituisco l'eventuale volume (se è chiusa)
|
|
return ( pSurf != nullptr && pSurf->GetVolume( dVol)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfFrNormVersor( int nId, int nRefId, Vector3d& vtNorm)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la Regione
|
|
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pSfr == nullptr)
|
|
return false ;
|
|
// recupero la normale
|
|
vtNorm = pSfr->GetNormVersor() ;
|
|
// gestione trasformazione ( eventuale)
|
|
return TransformVector( pGeomDB, nId, nRefId, vtNorm) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfFrGrossArea( int nId, double& dArea)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la Regione
|
|
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
|
|
// ne restituisco l'area senza eventuali buchi
|
|
return ( pSfr != nullptr && pSfr->GetGrossArea( dArea)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfFrTestExternal( int nId1, int nId2, double dMinDist)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la prima superficie FlatRegion
|
|
const ISurfFlatRegion* pSfr1 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId1)) ;
|
|
if ( pSfr1 == nullptr)
|
|
return false ;
|
|
// se richiesta distanza di sicurezza, ne faccio l'offset
|
|
PtrOwner<ISurfFlatRegion> pSfr1O ;
|
|
if ( abs( dMinDist) > 5 * EPS_SMALL) {
|
|
pSfr1O.Set( pSfr1->Clone()) ;
|
|
if ( IsNull( pSfr1O) || ! pSfr1O->Offset( dMinDist, ICurve::OFF_FILLET))
|
|
return false ;
|
|
pSfr1 = Get( pSfr1O) ;
|
|
}
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf1 ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId1, frSurf1))
|
|
return false ;
|
|
// recupero il tipo della seconda entità
|
|
int nType2 = pGeomDB->GetGeoType( nId2) ;
|
|
// se seconda entità regione
|
|
if ( nType2 == SRF_FLATRGN) {
|
|
// recupero la seconda superficie FlatRegion in locale alla prima
|
|
SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ;
|
|
const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ;
|
|
if ( pSfr2L == nullptr)
|
|
return false ;
|
|
// eseguo il test di intersezione tra le due regioni
|
|
for ( int i = 0 ; i < pSfr1->GetChunkCount() ; ++ i) {
|
|
for ( int j = 0 ; j < pSfr2L->GetChunkCount() ; ++ j) {
|
|
if ( pSfr1->GetChunkSimpleClassification( i, *pSfr2L, j) != REGC_OUT)
|
|
return false ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
// se altrimenti curva
|
|
else if ( (nType2 & GEO_CURVE) != 0) {
|
|
// recupero la curva in locale alla regione
|
|
CurveLocal Crv2Loc( pGeomDB, nId2, frSurf1) ;
|
|
const ICurve* pCrv2L = Crv2Loc.Get() ;
|
|
if ( pCrv2L == nullptr)
|
|
return false ;
|
|
// eseguo il test di intersezione tra regione e curva
|
|
for ( int i = 0 ; i < pSfr1->GetChunkCount() ; ++ i) {
|
|
PtrOwner<ICurve> pCrv1( pSfr1->GetLoop( i, 0)) ;
|
|
if ( pCrv1 == nullptr)
|
|
return false ;
|
|
IntersCurveCurve ccInt( *pCrv1, *pCrv2L) ;
|
|
CRVCVECTOR vcClass ;
|
|
if ( ! ccInt.GetCurveClassification( 1, EPS_SMALL, vcClass) || vcClass.empty())
|
|
return false ;
|
|
for ( auto& cClass : vcClass) {
|
|
if ( cClass.nClass == CRVC_IN || cClass.nClass == CRVC_ON_M ||
|
|
cClass.nClass == CRVC_ON_P || cClass.nClass == CRVC_NULL)
|
|
return false ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
// se altrimenti punto
|
|
else if ( nType2 == GEO_PNT3D) {
|
|
// recupero il punto
|
|
IGeoPoint3d* pGeoPt = GetGeoPoint3d( pGeomDB->GetGeoObj( nId2)) ;
|
|
Point3d ptP = pGeoPt->GetPoint() ;
|
|
// porto il punto in locale
|
|
Frame3d frPt ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId2, frPt))
|
|
return false ;
|
|
ptP.LocToLoc( frPt, frSurf1) ;
|
|
// determino se interno (comprende la frontiera)
|
|
bool bInside ;
|
|
if ( ! IsPointInsideSurfFr( ptP, pSfr1, 0, bInside))
|
|
return false ;
|
|
return ( ! bInside) ;
|
|
}
|
|
// altrimenti non valida
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeSurfFrChunkCount( int nId)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, 0)
|
|
// recupero la regione
|
|
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pSfr == nullptr)
|
|
return false ;
|
|
// recupero il numero di chunk
|
|
return pSfr->GetChunkCount() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfFrChunkMaxOffset( int nId, int nChunk, double& dMaxOffset)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la Regione
|
|
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
|
|
return ( pSfr != nullptr && pSfr->GetChunkMaxOffset( nChunk, dMaxOffset)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeSurfFrChunkSimpleClassify( int nId1, int nChunk1, int nId2, int nChunk2, double dToler)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, 0)
|
|
// recupero la prima superficie FlatRegion
|
|
ISurfFlatRegion* pSfr1 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId1)) ;
|
|
bool bOk = ( pSfr1 != nullptr) ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf1 ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId1, frSurf1) ;
|
|
// recupero la seconda superficie FlatRegion
|
|
const ISurfFlatRegion* pSfr2 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId2)) ;
|
|
bOk = bOk && ( pSfr2 != nullptr) ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf2 ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId2, frSurf2) ;
|
|
// se riferimenti diversi, porto una copia della seconda nel riferimento della prima
|
|
const ISurfFlatRegion* pSfr2L = pSfr2 ;
|
|
PtrOwner<ISurfFlatRegion> pTmp ;
|
|
if ( abs( dToler) > EPS_SMALL || ! AreSameFrame( frSurf1, frSurf2)) {
|
|
pTmp.Set( pSfr2->Clone()) ;
|
|
bOk = bOk && ! IsNull( pTmp) ;
|
|
bOk = bOk && pTmp->LocToLoc( frSurf2, frSurf1) ;
|
|
pTmp->Offset( -abs( dToler), ICurve::OFF_FILLET) ;
|
|
pSfr2L = pTmp ;
|
|
}
|
|
// classifico il chunk della prima regione rispetto a quello della seconda
|
|
int nRes = ( bOk ? pSfr1->GetChunkSimpleClassification( nChunk1, *pSfr2L, nChunk2) : REGC_NULL) ;
|
|
return nRes ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Resultati restituiti : REGC_NULL ( errore), REGC_OUT ( Chunks esterni), REGC_INTERS ( Chunk che si intersecano)
|
|
int
|
|
ExeSurfFlatRegionInterference( int nId1, int nChunk1, int nId2, int nChunk2, double dToler)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la prima superficie FlatRegion
|
|
ISurfFlatRegion* pSfr1 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId1)) ;
|
|
bool bOk = ( pSfr1 != nullptr) ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf1 ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId1, frSurf1) ;
|
|
// recupero la seconda superficie FlatRegion
|
|
const ISurfFlatRegion* pSfr2 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId2)) ;
|
|
bOk = bOk && ( pSfr2 != nullptr) ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf2 ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId2, frSurf2) ;
|
|
// se riferimenti diversi, porto una copia della seconda nel riferimento della prima
|
|
const ISurfFlatRegion* pSfr2L = pSfr2 ;
|
|
PtrOwner<ISurfFlatRegion> pTmp ;
|
|
if ( bOk && ( abs( dToler) > EPS_SMALL || ! AreSameFrame( frSurf1, frSurf2))) {
|
|
pTmp.Set( pSfr2->Clone()) ;
|
|
bOk = ( ! IsNull( pTmp)) ;
|
|
bOk = bOk && pTmp->LocToLoc( frSurf2, frSurf1) ;
|
|
pTmp->Offset( - abs( dToler), ICurve::OFF_FILLET) ;
|
|
pSfr2L = pTmp ;
|
|
}
|
|
// verifico interferenza del Chunk della prima regione rispetto a quello della seconda
|
|
int nRes = REGC_NULL ;
|
|
if ( bOk) {
|
|
bool bInterference = false ;
|
|
bOk = pSfr1->CheckChunkInterference( nChunk1, *pSfr2L, nChunk2, bInterference) ;
|
|
if ( bOk)
|
|
nRes = ( bInterference ? REGC_INTERS : REGC_OUT) ;
|
|
}
|
|
return nRes ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfFrChunkCenter( int nId, int nChunk, int nRefId, Point3d& ptCen, Vector3d& vtN)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie FlatRegion
|
|
ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pSfr == nullptr)
|
|
return false ;
|
|
// recupero il centro della parte
|
|
if ( ! pSfr->GetChunkCentroid( nChunk, ptCen))
|
|
return false ;
|
|
// recupero la normale della regione
|
|
vtN = pSfr->GetNormVersor() ;
|
|
// gestione trasformazioni ( eventuali)
|
|
return TransformPoint( pGeomDB, nId, nRefId, ptCen) && TransformVector( pGeomDB, nId, nRefId, vtN) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeExtractSurfFrChunkLoops( int nId, int nChunk, int nDestGrpId, int* pnCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie FlatRegion
|
|
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
|
|
bool bOk = ( pSfr != nullptr) ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ;
|
|
// recupero il riferimento di destinazione
|
|
Frame3d frDest ;
|
|
bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ;
|
|
// richiedo i contorni del componente connesso (chunk) e li inserisco nel DB
|
|
int nFirstId = GDB_ID_NULL ;
|
|
int nCount = 0 ;
|
|
int nL = 0 ;
|
|
PtrOwner<ICurve> pCrv( bOk ? pSfr->GetLoop( nChunk, nL) : nullptr) ;
|
|
while ( ! IsNull( pCrv)) {
|
|
// porto la curva nel riferimento destinazione
|
|
bOk = bOk && pCrv->LocToLoc( frSurf, frDest) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrv)) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nNewId != GDB_ID_NULL) ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( bOk && nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
if ( bOk)
|
|
++ nCount ;
|
|
// passo alla prossima curva
|
|
pCrv.Set( bOk ? pSfr->GetLoop( nChunk, ++nL) : nullptr) ;
|
|
}
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtExtractSurfFrChunkLoops(" + ToString( nId) + "," +
|
|
ToString( nChunk) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
return nFirstId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeSurfTmVertexCount( int nId)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, 0)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return 0 ;
|
|
// recupero il numero di vertici
|
|
return pStm->GetVertexCount() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeSurfTmFacetCount( int nId)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, 0)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return 0 ;
|
|
// recupero il numero delle facce
|
|
return pStm->GetFacetCount() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeSurfTmPartCount( int nId)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, -1)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return -1 ;
|
|
// recupero il numero di parti
|
|
return pStm->GetPartCount() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmGetPartAndShellFromFacet( int nIdSurfTm, int nIdFacet, int& nPart, int& nShell)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nIdSurfTm)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero la parte e la shell a cui appartiene la faccia passata
|
|
return pStm->GetPartAndShellFromFacet( nIdFacet, nPart, nShell) ;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmGetVertex( int nId, int nVert, int nRefId, Point3d& ptVert)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero il vertice di indice dato
|
|
if ( ! pStm->GetVertex( nVert, ptVert))
|
|
return false ;
|
|
// gestione trasformazioni ( eventuali)
|
|
return TransformPoint( pGeomDB, nId, nRefId, ptVert) ;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmGetNearestVertex( int nId, const Point3d& ptNear, int nRefId, int& nVert, Point3d& ptVert)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// porto il punto Near nel riferimento dell'entità
|
|
Point3d ptNearL = ptNear ;
|
|
if ( ! InvTransformPoint( pGeomDB, nId, nRefId, ptNearL))
|
|
return false ;
|
|
// recupero il vertice più vicino della superficie
|
|
nVert = GetSurfTmNearestVertex( ptNearL, *pStm) ;
|
|
if ( ! pStm->GetVertex( nVert, ptVert))
|
|
return false ;
|
|
// gestione trasformazioni ( eventuali)
|
|
return TransformPoint( pGeomDB, nId, nRefId, ptVert) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmTriangleNormVersor( int nId, int nTria, int nRefId, Vector3d& vtNorm)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero il triangolo
|
|
Triangle3d Tria ;
|
|
if ( ! pStm->GetTriangle( nTria, Tria))
|
|
return false ;
|
|
// assegno la normale
|
|
vtNorm = Tria.GetN() ;
|
|
// gestione trasformazione ( eventuale)
|
|
return TransformVector( pGeomDB, nId, nRefId, vtNorm) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeSurfTmFacetFromTria( int nId, int nT)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, SVT_NULL)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return SVT_NULL ;
|
|
// recupero il numero della faccia da quello di un suo triangolo
|
|
return pStm->GetFacetFromTria( nT) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmFacetAdjacencies( int nId, int nFacet, INTMATRIX& vAdj)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
bool bOk = ( pStm != nullptr) ;
|
|
// recupero le adiacenze
|
|
bOk = bOk && pStm->GetFacetAdjacencies( nFacet, vAdj) ;
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmFacetNearestEndPoint( int nId, int nFacet, const Point3d& ptNear, int nRefId,
|
|
Point3d& ptEnd, Vector3d& vtN)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// porto il punto Near nel riferimento dell'entità
|
|
Point3d ptNearL = ptNear ;
|
|
if ( ! InvTransformPoint( pGeomDB, nId, nRefId, ptNearL))
|
|
return false ;
|
|
// recupero il punto End più vicino della faccia
|
|
if ( ! pStm->GetFacetNearestEndPoint( nFacet, ptNearL, ptEnd, vtN))
|
|
return false ;
|
|
// gestione trasformazioni ( eventuali)
|
|
return TransformPoint( pGeomDB, nId, nRefId, ptEnd) && TransformVector( pGeomDB, nId, nRefId, vtN) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmFacetNearestMidPoint( int nId, int nFacet, const Point3d& ptNear, int nRefId,
|
|
Point3d& ptMid, Vector3d& vtN)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// porto il punto Near nel riferimento dell'entità
|
|
Point3d ptNearL = ptNear ;
|
|
if ( ! InvTransformPoint( pGeomDB, nId, nRefId, ptNearL))
|
|
return false ;
|
|
// recupero il punto Mid più vicino della faccia
|
|
if ( ! pStm->GetFacetNearestMidPoint( nFacet, ptNearL, ptMid, vtN))
|
|
return false ;
|
|
// gestione trasformazioni ( eventuali)
|
|
return TransformPoint( pGeomDB, nId, nRefId, ptMid) && TransformVector( pGeomDB, nId, nRefId, vtN) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmFacetCenter( int nId, int nFacet, int nRefId, Point3d& ptCen, Vector3d& vtN)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero il centro della faccia
|
|
if ( ! pStm->GetFacetCenter( nFacet, ptCen, vtN))
|
|
return false ;
|
|
// gestione trasformazioni ( eventuali)
|
|
return TransformPoint( pGeomDB, nId, nRefId, ptCen) && TransformVector( pGeomDB, nId, nRefId, vtN) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmFacetNormVersor( int nId, int nFacet, int nRefId, Vector3d& vtNorm)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero la normale della faccia
|
|
if ( ! pStm->GetFacetNormal( nFacet, vtNorm))
|
|
return false ;
|
|
// gestione trasformazione ( eventuale)
|
|
return TransformVector( pGeomDB, nId, nRefId, vtNorm) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmFacetMinAreaRectangle( int nId, int nFacet, int nRefId, Frame3d& frRect, double& dDimX, double& dDimY)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero il centro e la normale della faccia
|
|
Point3d ptCen ; Vector3d vtN ;
|
|
if ( ! pStm->GetFacetCenter( nFacet, ptCen, vtN))
|
|
return false ;
|
|
// calcolo il riferimento OCS della faccia
|
|
Frame3d frFac ;
|
|
if ( ! frFac.Set( ptCen, vtN))
|
|
return false ;
|
|
// recupero il contorno esterno della faccia e lo porto nel suo riferimento
|
|
POLYLINEVECTOR vPL ;
|
|
pStm->GetFacetLoops( nFacet, vPL) ;
|
|
if ( vPL.empty())
|
|
return false ;
|
|
vPL[0].ToLoc( frFac) ;
|
|
// derivo il rettangolo in XY di area minima di questa
|
|
Point3d ptOri ;
|
|
Vector3d vtAx ;
|
|
if ( ! vPL[0].GetMinAreaRectangleXY( ptOri, vtAx, dDimX, dDimY) || ! frRect.Set( ptOri, Z_AX, vtAx))
|
|
return false ;
|
|
// esprimo il riferimento rispetto a quello richiesto
|
|
frRect.ToGlob( frFac) ;
|
|
return TransformFrame( pGeomDB, nId, nRefId, frRect) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmFacetElevationInBBox( int nId, int nFacet, const BBox3d& b3Box, bool bAcceptOutFacet, int nRefId, double& dElev)
|
|
{
|
|
// La faccia deve essere tutta contenuta nel Box
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh e il suo riferimento
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
Frame3d frStm ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frStm))
|
|
return false ;
|
|
// verifico il box e ne recupero il riferimento
|
|
if ( b3Box.IsEmpty())
|
|
return false ;
|
|
Frame3d frBox ;
|
|
if ( nRefId == GDB_ID_ROOT)
|
|
frBox = GLOB_FRM ;
|
|
else if ( nRefId == GDB_ID_GRID)
|
|
frBox = pGeomDB->GetGridFrame() ;
|
|
else {
|
|
// nRefId può essere un gruppo o una entità
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nRefId, frBox) &&
|
|
! pGeomDB->GetGlobFrame( nRefId, frBox))
|
|
return false ;
|
|
}
|
|
// recupero il contorno esterno della faccia e lo porto nel riferimento del box
|
|
POLYLINEVECTOR vPL ;
|
|
pStm->GetFacetLoops( nFacet, vPL) ;
|
|
if ( vPL.empty())
|
|
return false ;
|
|
vPL[0].LocToLoc( frStm, frBox) ;
|
|
// ne derivo il poligono
|
|
Polygon3d pgFacet ;
|
|
if ( ! pgFacet.FromPolyLine( vPL[0]))
|
|
return false ;
|
|
// calcolo l'elevazione
|
|
return PolygonElevationInBBox( pgFacet, b3Box, bAcceptOutFacet, dElev) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmFacetElevationInClosedSurfTm( int nFacetStmId, int nFacet, int nClosedStmId, bool bAcceptOutFacet, double& dElev)
|
|
{
|
|
// La faccia deve essere tutta contenuta nel Box
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh della faccia e il suo riferimento
|
|
const ISurfTriMesh* pFacStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nFacetStmId)) ;
|
|
if ( pFacStm == nullptr)
|
|
return false ;
|
|
Frame3d frFacStm ;
|
|
if ( ! pGeomDB->GetGlobFrame( nFacetStmId, frFacStm))
|
|
return false ;
|
|
// recupero la superficie trimesh chiusa (volume)
|
|
const ISurfTriMesh* pCldStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nClosedStmId)) ;
|
|
if ( pCldStm == nullptr)
|
|
return false ;
|
|
Frame3d frCldStm ;
|
|
if ( ! pGeomDB->GetGlobFrame( nClosedStmId, frCldStm))
|
|
return false ;
|
|
// recupero il contorno esterno della faccia e lo porto nel riferimento della superficie chiusa
|
|
POLYLINEVECTOR vPL ;
|
|
pFacStm->GetFacetLoops( nFacet, vPL) ;
|
|
if ( vPL.empty())
|
|
return false ;
|
|
vPL[0].LocToLoc( frFacStm, frCldStm) ;
|
|
// ne derivo il poligono
|
|
Polygon3d pgFacet ;
|
|
if ( ! pgFacet.FromPolyLine( vPL[0]))
|
|
return false ;
|
|
// calcolo l'elevazione
|
|
return PolygonElevationInClosedSurfTm( pgFacet, *pCldStm, bAcceptOutFacet, dElev) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmFacetOppositeSide( int nId, int nFacet, const Vector3d& vtDir, int nRefId,
|
|
Point3d& ptP1, Point3d& ptP2)
|
|
{
|
|
Point3d ptPm ;
|
|
Vector3d vtIn1, vtOut2;
|
|
double dLen, dWidth ;
|
|
return ExeSurfTmFacetOppositeSideEx( nId, nFacet, vtDir, nRefId, ptP1, ptPm, ptP2, vtIn1, vtOut2, dLen, dWidth) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmFacetOppositeSideEx( int nId, int nFacet, const Vector3d& vtDir, int nRefId,
|
|
Point3d& ptP1, Point3d& ptPm, Point3d& ptP2, Vector3d& vtIn1, Vector3d& vtOut2, double& dLen, double& dWidth)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero il riferimento della trimesh
|
|
Frame3d frStm ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frStm))
|
|
return false ;
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero i contorni della faccia
|
|
POLYLINEVECTOR vPL ;
|
|
pStm->GetFacetLoops( nFacet, vPL) ;
|
|
if ( vPL.empty())
|
|
return false ;
|
|
// recupero la normale esterna della faccia
|
|
Point3d ptCen ;
|
|
Vector3d vtN ;
|
|
if ( ! pStm->GetFacetCenter( nFacet, ptCen, vtN))
|
|
return false ;
|
|
// creo la curva a partire dal contorno esterno
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( vPL[0]))
|
|
return false ;
|
|
// unisco parti allineate
|
|
pCrvCompo->MergeCurves( LIN_TOL_STD, ANG_TOL_STD_DEG) ;
|
|
// porto la direzione nel riferimento della superficie
|
|
Vector3d vtDirL = vtDir ;
|
|
if ( ! InvTransformVector( pGeomDB, nId, nRefId, vtDirL))
|
|
return false ;
|
|
// costruisco un riferimento con Z su normale e X vicino a direzione
|
|
Frame3d frSpec ;
|
|
if ( ! frSpec.Set( ptCen, vtN, vtDirL))
|
|
return false ;
|
|
// porto il contorno in questo riferimento
|
|
pCrvCompo->ToLoc( frSpec) ;
|
|
// ne faccio una copia per usi successivi
|
|
PtrOwner<ICurveComposite> pCrvCopy( pCrvCompo->Clone()) ;
|
|
// la direzione di riferimento è l'asse X, la sostituisco con quella perpendicolare alla curva più adatta
|
|
Vector3d vtRef = X_AX ;
|
|
double dCosMax = -1 ;
|
|
const ICurve* pCrv = pCrvCompo->GetFirstCurve() ;
|
|
while ( pCrv != nullptr) {
|
|
Vector3d vtDir ; pCrv->GetMidDir( vtDir) ;
|
|
Vector3d vtPerp = Z_AX ^ vtDir ;
|
|
double dCos = vtPerp * X_AX ;
|
|
if ( dCos > dCosMax) {
|
|
dCosMax = dCos ;
|
|
vtRef = vtPerp ;
|
|
}
|
|
pCrv = pCrvCompo->GetNextCurve() ;
|
|
}
|
|
// la curva gira in senso antiorario attorno al contorno faccia vista dalla normale uscente
|
|
// elimino i segmenti che hanno la direzione di riferimento a destra o quasi (46deg)
|
|
const double COS_ANG_MAX = cos( 46.01 * DEGTORAD) ;
|
|
const double MIN_DIR_LEN = 0.999 ;
|
|
// cerco primo elemento del contorno non valido e vi pongo inizio/fine della curva
|
|
int i = 0 ;
|
|
pCrv = pCrvCompo->GetFirstCurve() ;
|
|
while ( pCrv != nullptr) {
|
|
double dCrvLen = 0 ; pCrv->GetLength( dCrvLen) ;
|
|
Vector3d vtDir ; pCrv->GetMidDir( vtDir) ;
|
|
if ( dCrvLen > MIN_DIR_LEN && ( Z_AX ^ vtDir) * vtRef < COS_ANG_MAX) {
|
|
vtIn1 = vtDir ;
|
|
vtOut2 = vtDir ;
|
|
pCrvCompo->ChangeStartPoint( i) ;
|
|
break ;
|
|
}
|
|
pCrv = pCrvCompo->GetNextCurve() ;
|
|
++ i ;
|
|
}
|
|
// se non trovato almeno un lato non valido, errore
|
|
if ( pCrv == nullptr)
|
|
return false ;
|
|
// a partire da questo elimino elementi non validi in avanti e indietro
|
|
pCrv = pCrvCompo->GetFirstCurve() ;
|
|
while ( pCrv != nullptr) {
|
|
Vector3d vtDir ; pCrv->GetMidDir( vtDir) ;
|
|
if ( ( Z_AX ^ vtDir) * vtRef < COS_ANG_MAX) {
|
|
double dCrvLen = 0 ; pCrv->GetLength( dCrvLen) ;
|
|
if ( dCrvLen > MIN_DIR_LEN)
|
|
pCrv->GetMidDir( vtIn1) ;
|
|
delete( pCrvCompo->RemoveFirstOrLastCurve( false)) ;
|
|
pCrv = pCrvCompo->GetFirstCurve() ;
|
|
}
|
|
else
|
|
break ;
|
|
}
|
|
pCrv = pCrvCompo->GetLastCurve() ;
|
|
while ( pCrv != nullptr) {
|
|
Vector3d vtDir ; pCrv->GetMidDir( vtDir) ;
|
|
if ( ( Z_AX ^ vtDir) * vtRef < COS_ANG_MAX) {
|
|
double dCrvLen = 0 ; pCrv->GetLength( dCrvLen) ;
|
|
if ( dCrvLen > MIN_DIR_LEN)
|
|
pCrv->GetMidDir( vtOut2) ;
|
|
delete( pCrvCompo->RemoveFirstOrLastCurve( true)) ;
|
|
pCrv = pCrvCompo->GetLastCurve() ;
|
|
}
|
|
else
|
|
break ;
|
|
}
|
|
// elimino le curve estreme molto corte ( 0.5 mm)
|
|
const double REF_LEN = 10.0 ;
|
|
double dCompoLen ;
|
|
if ( pCrvCompo->GetLength( dCompoLen) && dCompoLen > REF_LEN) {
|
|
const double MIN_LEN = 0.5 ;
|
|
double dCrvLen ;
|
|
pCrv = pCrvCompo->GetFirstCurve() ;
|
|
if ( pCrv != nullptr && pCrv->GetLength( dCrvLen) && dCrvLen < MIN_LEN)
|
|
delete( pCrvCompo->RemoveFirstOrLastCurve( false)) ;
|
|
pCrv = pCrvCompo->GetLastCurve() ;
|
|
if ( pCrv != nullptr && pCrv->GetLength( dCrvLen) && dCrvLen < MIN_LEN)
|
|
delete( pCrvCompo->RemoveFirstOrLastCurve( true)) ;
|
|
}
|
|
// recupero i punti estremi della curva
|
|
if ( ! pCrvCompo->GetStartPoint( ptP1) || ! pCrvCompo->GetEndPoint( ptP2))
|
|
return false ;
|
|
// ricavo il punto intermedio
|
|
if ( pCrvCompo->GetCurveCount() == 1)
|
|
ptPm = Media( ptP1, ptP2, 0.5) ;
|
|
else if ( pCrvCompo->GetCurveCount() == 2)
|
|
pCrvCompo->GetPointD1D2( 1.0, ICurve::FROM_MINUS, ptPm) ;
|
|
else {
|
|
double dLen ;
|
|
pCrvCompo->GetLength( dLen) ;
|
|
double dU ;
|
|
pCrvCompo->GetParamAtLength( 0.5 * dLen, dU) ;
|
|
pCrvCompo->GetPointD1D2( dU, ICurve::FROM_MINUS, ptPm) ;
|
|
}
|
|
// determino la lunghezza e l'elevazione della faccia rispetto alla curva trovata
|
|
Vector3d vtTg = ptP2 - ptP1 ;
|
|
Frame3d frExtr ;
|
|
if ( ! frExtr.Set( ORIG, Z_AX, vtTg) || ! frExtr.Invert())
|
|
return false ;
|
|
BBox3d b3Extr ; pCrvCopy->GetBBox( frExtr, b3Extr) ;
|
|
if ( ! b3Extr.IsEmpty()) {
|
|
dLen = b3Extr.GetMax().x - b3Extr.GetMin().x ;
|
|
dWidth = b3Extr.GetMax().y - b3Extr.GetMin().y ;
|
|
}
|
|
else {
|
|
dLen = 0 ;
|
|
dWidth = 0 ;
|
|
}
|
|
// porto i punti nel riferimento della superficie e poi in quello richiesto
|
|
ptP1.ToGlob( frSpec) ;
|
|
ptPm.ToGlob( frSpec) ;
|
|
ptP2.ToGlob( frSpec) ;
|
|
vtIn1.ToGlob( frSpec) ;
|
|
vtOut2.ToGlob( frSpec) ;
|
|
return ( TransformPoint( pGeomDB, nId, nRefId, ptP1) &&
|
|
TransformPoint( pGeomDB, nId, nRefId, ptPm) &&
|
|
TransformPoint( pGeomDB, nId, nRefId, ptP2) &&
|
|
TransformVector( pGeomDB, nId, nRefId, vtIn1) &&
|
|
TransformVector( pGeomDB, nId, nRefId, vtOut2)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmFacetsContact( int nId, int nF1, int nF2, int nRefId, bool& bAdjac, Point3d& ptP1, Point3d& ptP2, double& dAng)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero i dati di contatto tra le due facce
|
|
if ( ! pStm->GetFacetsContact( nF1, nF2, bAdjac, ptP1, ptP2, dAng))
|
|
return false ;
|
|
// gestione trasformazione ( eventuale)
|
|
if ( bAdjac)
|
|
return TransformPoint( pGeomDB, nId, nRefId, ptP1) && TransformPoint( pGeomDB, nId, nRefId, ptP2) ;
|
|
else
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeExtractSurfTmLoops( int nId, int nDestGrpId, int* pnCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
bool bOk = ( pStm != nullptr) ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ;
|
|
// recupero il riferimento di destinazione
|
|
Frame3d frDest ;
|
|
bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ;
|
|
// recupero i loop come polilinee
|
|
POLYLINEVECTOR vPL ;
|
|
bOk = bOk && pStm->GetLoops( vPL) ;
|
|
// dalle polilinee creo le curve e le inserisco nel DB
|
|
int nFirstId = GDB_ID_NULL ;
|
|
int nCount = 0 ;
|
|
for ( size_t i = 0 ; i < vPL.size() ; ++ i) {
|
|
// creo la curva
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
bOk = bOk && pCrvCompo->FromPolyLine( vPL[i]) ;
|
|
// la porto nel riferimento destinazione
|
|
bOk = bOk && pCrvCompo->LocToLoc( frSurf, frDest) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nNewId != GDB_ID_NULL) ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( bOk && nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
if ( bOk)
|
|
++ nCount ;
|
|
}
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtExtractSurfTmLoops(" + ToString( nId) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
return nFirstId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeGetSurfTmSilhouette( int nId, const Vector3d& vtDir, double dToler, int nDestGrpId, int nRefType,
|
|
int* pnCount, bool bAllTria)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
bool bOk = ( pStm != nullptr) ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ;
|
|
// recupero il riferimento di destinazione
|
|
Frame3d frDest ;
|
|
bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ;
|
|
// porto in locale alla superficie il versore di riferimento
|
|
Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frSurf) ;
|
|
// recupero i loop come polilinee
|
|
POLYLINEVECTOR vPL ;
|
|
bOk = bOk && pStm->GetSilhouette( vtDirL, dToler, vPL, bAllTria) ;
|
|
// dalle polilinee creo le curve e le inserisco nel DB
|
|
int nFirstId = GDB_ID_NULL ;
|
|
int nCount = 0 ;
|
|
for ( size_t i = 0 ; i < vPL.size() ; ++ i) {
|
|
// creo la curva
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
bOk = bOk && pCrvCompo->FromPolyLine( vPL[i]) ;
|
|
// la porto nel riferimento destinazione
|
|
bOk = bOk && pCrvCompo->LocToLoc( frSurf, frDest) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nNewId != GDB_ID_NULL) ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( bOk && nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
if ( bOk)
|
|
++ nCount ;
|
|
}
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtGetSurfTmSilhouette(" + ToString( nId) + ",{" +
|
|
ToString( vtDir) + "}," +
|
|
ToString( nDestGrpId) + "," +
|
|
RefTypeToString( nRefType) + "," +
|
|
ToString( bAllTria) + ")" +
|
|
" -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
return nFirstId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
static int
|
|
MyGetSurfTmParSilhouettes( const INTVECTOR& vIds, const Point3d& ptOn, const Vector3d& vtN, const DBLVECTOR& vdDist,
|
|
double dToler, int nDestGrpId, int nRefType, int& nCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// inizializzo contatore a valore negativo (errore)
|
|
nCount = -1 ;
|
|
// se non ci sono superfici o quote di calcolo, non c'è niente da calcolare
|
|
if ( vIds.empty() || vdDist.empty())
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento della prima superficie
|
|
Frame3d frSurf ;
|
|
if ( ! pGeomDB->GetGlobFrame( vIds[0], frSurf))
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
// recupero le superfici TriMesh e le porto tutte in locale alla prima
|
|
SURFLOCALVECTOR vSurfL ; vSurfL.reserve( vIds.size()) ;
|
|
CISURFTMPVECTOR vpStm ; vpStm.reserve( vIds.size()) ;
|
|
for ( int i = 0 ; i < int( vIds.size()) ; ++ i) {
|
|
vSurfL.emplace_back( pGeomDB, vIds[i], frSurf) ;
|
|
if ( vSurfL[i].Get() == nullptr)
|
|
return GDB_ID_NULL ;
|
|
vpStm.emplace_back( GetSurfTriMesh( vSurfL[i].Get())) ;
|
|
}
|
|
// porto in locale alla superficie il punto e la normale e ne calcolo un riferimento
|
|
Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frSurf) ;
|
|
Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frSurf) ;
|
|
Frame3d frPlanes ;
|
|
if ( ! frPlanes.Set( ptOnL, vtNL))
|
|
return GDB_ID_NULL ;
|
|
// recupero i contorni delle varie silhouette
|
|
int nFirstId = GDB_ID_NULL ;
|
|
int nTempCount = 0 ;
|
|
PtrOwner<ICAvParSilhouettesSurfTm> pCavParSilh( CreateCAvParSilhouettesSurfTm()) ;
|
|
if ( IsNull( pCavParSilh) || ! pCavParSilh->SetData( vpStm, frPlanes, dToler))
|
|
return GDB_ID_NULL ;
|
|
for ( auto dDist : vdDist) {
|
|
// recupero i loop come polilinee
|
|
POLYLINEVECTOR vPL ;
|
|
if ( ! pCavParSilh->GetSilhouette( dDist, vPL))
|
|
return GDB_ID_NULL ;
|
|
// dalle polilinee creo le curve e le inserisco nel DB
|
|
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
|
// creo la curva
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( ! pCrvCompo->FromPolyLine( vPL[i]))
|
|
return GDB_ID_NULL ;
|
|
// assegno direzione di estrusione
|
|
pCrvCompo->SetExtrusion( vtNL) ;
|
|
// la porto nel riferimento destinazione
|
|
pCrvCompo->LocToLoc( frSurf, frDest) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( vIds[0], nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nTempCount ;
|
|
}
|
|
}
|
|
nCount = nTempCount ;
|
|
return nFirstId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeGetSurfTmParSilhouettes( const INTVECTOR& vIds, const Point3d& ptOn, const Vector3d& vtN, const DBLVECTOR& vdDist,
|
|
double dToler, int nDestGrpId, int nRefType, int* pnCount)
|
|
{
|
|
// eseguo
|
|
int nCount = -1 ;
|
|
int nFirstId = MyGetSurfTmParSilhouettes( vIds, ptOn, vtN, vdDist, dToler, nDestGrpId, nRefType, nCount) ;
|
|
// aggiorno contatori
|
|
if ( nFirstId != GDB_ID_NULL)
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtGetSurfTmParSilhouettes({" + ToString( vIds) + "},{" +
|
|
ToString( ptOn) + "},{" +
|
|
ToString( vtN) + "},{" +
|
|
ToString( vdDist) + "}," +
|
|
ToString( dToler) + "," +
|
|
ToString( nDestGrpId) + "," +
|
|
RefTypeToString( nRefType) + ")" +
|
|
" -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
return nFirstId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeExtractSurfTmFacetLoops( int nId, int nFacet, int nDestGrpId, int* pnCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
bool bOk = ( pStm != nullptr) ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ;
|
|
// recupero il riferimento di destinazione
|
|
Frame3d frDest ;
|
|
bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ;
|
|
// recupero la normale della faccia (da usare come estrusione delle curve)
|
|
Vector3d vtN ;
|
|
bOk = bOk && pStm->GetFacetNormal( nFacet, vtN) ;
|
|
// recupero i loop come polilinee
|
|
POLYLINEVECTOR vPL ;
|
|
bOk = bOk && pStm->GetFacetLoops( nFacet, vPL) ;
|
|
// dalle polilinee creo le curve e le inserisco nel DB
|
|
int nFirstId = GDB_ID_NULL ;
|
|
int nCount = 0 ;
|
|
for ( size_t i = 0 ; i < vPL.size() ; ++ i) {
|
|
// creo la curva
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
bOk = bOk && pCrvCompo->FromPolyLine( vPL[i]) ;
|
|
// imposto estrusione
|
|
bOk = bOk && pCrvCompo->SetExtrusion( vtN) ;
|
|
// la porto nel riferimento destinazione
|
|
bOk = bOk && pCrvCompo->LocToLoc( frSurf, frDest) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nNewId != GDB_ID_NULL) ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( bOk && nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
if ( bOk)
|
|
++ nCount ;
|
|
}
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtExtractSurfTmFacetLoops(" + ToString( nId) + "," +
|
|
ToString( nFacet) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
return nFirstId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeExtractSurfTmTriaLoop( int nId, int nT, int nDestGrpId)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return GDB_ID_NULL ;
|
|
bool bOk = true ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ;
|
|
// recupero il riferimento di destinazione
|
|
Frame3d frDest ;
|
|
bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ;
|
|
// recupero la normale del trinagolo (da usare come estrusione della curva)
|
|
Triangle3d tria ; pStm->GetTriangle(nT, tria) ;
|
|
Vector3d vtN = tria.GetN() ;
|
|
// creo il loop come poliline
|
|
PolyLine PL ;
|
|
for ( int i = 0 ; i < 3 ; ++i)
|
|
PL.AddUPoint( i, tria.GetP(i)) ;
|
|
PL.Close() ;
|
|
// dalla polilinea creo la curva e la inserisco nel DB
|
|
// creo la curva
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
bOk = bOk && pCrvCompo->FromPolyLine( PL) ;
|
|
// imposto estrusione
|
|
bOk = bOk && pCrvCompo->SetExtrusion( vtN) ;
|
|
// la porto nel riferimento destinazione
|
|
bOk = bOk && pCrvCompo->LocToLoc( frSurf, frDest) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nNewId != GDB_ID_NULL) ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtExtractSurfTmTriaLoop(" + ToString( nId) + "," +
|
|
ToString( nT) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id=" + ToString( nNewId) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco il risultato
|
|
return nNewId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
ExeCopySurfTmFacet( int nId, int nFacet, int nDestGrpId)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// recupero il suo riferimento globale
|
|
Frame3d frSurf ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frSurf))
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
// copio la faccia
|
|
PtrOwner<ISurfTriMesh> pFac( pStm->CloneFacet( nFacet)) ;
|
|
if ( IsNull( pFac))
|
|
return GDB_ID_NULL ;
|
|
pFac->LocToLoc( frSurf, frDest) ;
|
|
// inserisco nel DB
|
|
int nFacId = pGeomDB->InsertGeoObj( GDB_ID_NULL, nDestGrpId, GDB_LAST_SON, Release( pFac)) ;
|
|
if ( nFacId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// copio gli attributi
|
|
if ( ! pGeomDB->CopyAttributes( nId, nFacId))
|
|
return GDB_ID_NULL ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtCopySurfTmFacet(" + ToString( nId) + "," +
|
|
ToString( nFacet) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id=" + ToString( nFacId) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
return nFacId ;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmGetAllVertInFacet( int nId, int nFacet, INTVECTOR& vVert)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero l'elenco dei vertici nella faccia
|
|
return pStm->GetAllVertInFacet( nFacet, vVert) ;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmGetFacetBBox( int nId, int nFacet, int nFlag, BBox3d& b3Box)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero il bounding box della faccia dell'oggetto in locale
|
|
return pStm->GetFacetLocalBBox( nFacet, b3Box, nFlag) ;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmGetFacetBBoxGlob( int nId, int nFacet, int nFlag, BBox3d& b3Box)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero il riferimento globale del gruppo cui appartiene
|
|
Frame3d frGlob ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frGlob))
|
|
return false ;
|
|
// recupero il bounding box della faccia dell'oggetto in globale
|
|
return pStm->GetFacetBBox( nFacet, frGlob, b3Box, nFlag) ;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmGetFacetBBoxRef( int nId, int nFacet, int nFlag, const Frame3d& frRef, BBox3d& b3Box)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero il riferimento globale del gruppo cui appartiene
|
|
Frame3d frGlob ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frGlob))
|
|
return false ;
|
|
// porto il riferimento di espressione in quello della superficie
|
|
Frame3d frGlobL = frGlob ;
|
|
frGlobL.ToLoc( frRef) ;
|
|
// recupero il bounding box della faccia dell'oggetto in globale
|
|
return pStm->GetFacetBBox( nFacet, frGlobL, b3Box, nFlag) ;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmGetFacetOutlineInfo( int nId, int nFacet, int nRefId,
|
|
int& nStatus, BOOLVECTOR& vbOpen, INTVECTOR& vnAdj, DBLVECTOR& vdLen,
|
|
PNTVECTOR& vptStart, VCT3DVECTOR& vvtNorm, DBLVECTOR& vdElev)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero normale della faccia
|
|
Vector3d vtNorm ;
|
|
if ( ! pStm->GetFacetNormal( nFacet, vtNorm))
|
|
return false ;
|
|
// recupero i loop come polilinee
|
|
POLYLINEVECTOR vPL ;
|
|
if ( ! pStm->GetFacetLoops( nFacet, vPL) || vPL.empty())
|
|
return false ;
|
|
// calcolo lo stato
|
|
if ( vPL.size() == 1)
|
|
nStatus = 0 ;
|
|
else {
|
|
nStatus = -1 ;
|
|
for ( int i = 1 ; nStatus == -1 && i < int( vPL.size()) ; ++ i) {
|
|
double dIni, dFin ;
|
|
Point3d ptIni, ptFin ;
|
|
bool bFound = vPL[i].GetFirstULine( &dIni, &ptIni, &dFin, &ptFin) ;
|
|
while ( bFound) {
|
|
int nAdj = lround( dIni) ;
|
|
Vector3d vtNf ;
|
|
if ( nAdj >= 0 && pStm->GetFacetNormal( nAdj, vtNf)) {
|
|
Vector3d vtTg = ptFin - ptIni ;
|
|
vtTg.Normalize() ;
|
|
if ( ( vtTg ^ vtNf) * vtNorm > EPS_SMALL) {
|
|
nStatus = 1 ;
|
|
break ;
|
|
}
|
|
}
|
|
bFound = vPL[i].GetNextULine( &dIni, &ptIni, &dFin, &ptFin) ;
|
|
}
|
|
}
|
|
}
|
|
// pulisco e prealloco i vettori del risultato
|
|
int nDim = vPL[0].GetLineNbr() ;
|
|
vbOpen.clear() ; vbOpen.reserve( nDim) ;
|
|
vnAdj.clear() ; vnAdj.reserve( nDim) ;
|
|
vdLen.clear() ; vdLen.reserve( nDim) ;
|
|
vptStart.clear() ; vptStart.reserve( nDim) ;
|
|
vvtNorm.clear() ; vvtNorm.reserve( nDim) ;
|
|
vdElev.clear() ; vdElev.reserve( nDim) ;
|
|
// recupero riferimento alla lista dei punti
|
|
PNTULIST& lstPU = vPL[0].GetUPointList() ;
|
|
// ciclo sui lati del loop esterno (il primo)
|
|
double dIni, dFin ;
|
|
Point3d ptIni, ptFin ;
|
|
bool bFound = vPL[0].GetFirstULine( &dIni, &ptIni, &dFin, &ptFin) ;
|
|
while ( bFound) {
|
|
// faccia adiacente
|
|
int nAdj = lround( dIni) ;
|
|
// lunghezza lato
|
|
double dLen = Dist( ptIni, ptFin) ;
|
|
// aperto se senza adiacenza o con faccia adiacente che va da parte negativa (tipo foro)
|
|
bool bOpen = true ;
|
|
Vector3d vtTg = ptFin - ptIni ;
|
|
vtTg.Normalize() ;
|
|
Vector3d vtNf ;
|
|
if ( nAdj >= 0 && pStm->GetFacetNormal( nAdj, vtNf))
|
|
bOpen = ((vtTg ^ vtNf) * vtNorm < EPS_SMALL) ;
|
|
// normale al lato (verso interno se chiuso, verso esterno se aperto)
|
|
Vector3d vtN = vtTg ;
|
|
vtN.Rotate( vtNorm, 0, ( bOpen ? -1 : 1)) ;
|
|
// elevazione secondo direzione della normale al lato
|
|
double dElev = 0 ;
|
|
for ( const auto& PU : lstPU) {
|
|
double dDist = ( PU.first - ptIni) * vtN ;
|
|
dElev = ( bOpen ? min( dElev, dDist) : max( dElev, dDist)) ;
|
|
}
|
|
// porto punto iniziale nel riferimento desiderato
|
|
TransformPoint( pGeomDB, nId, nRefId, ptIni) ;
|
|
// porto normale nel riferimento desiderato
|
|
TransformVector( pGeomDB, nId, nRefId, vtN) ;
|
|
// inserisco dati nei parametri di ritorno
|
|
vbOpen.emplace_back( bOpen) ;
|
|
vnAdj.emplace_back( nAdj) ;
|
|
vdLen.emplace_back( dLen) ;
|
|
vptStart.emplace_back( ptIni) ;
|
|
vvtNorm.emplace_back( vtN) ;
|
|
vdElev.emplace_back( dElev) ;
|
|
// passo al prossimo lato
|
|
bFound = vPL[0].GetNextULine( &dIni, &ptIni, &dFin, &ptFin) ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeSurfTmGetEdges( int nId, int nDestGrpId, bool bSmoothAng, int* pnCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
bool bOk = ( pStm != nullptr) ;
|
|
// recupero il riferimento globale del gruppo cui appartiene
|
|
Frame3d frSurf ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ;
|
|
// recupero il riferimento di destinazione
|
|
Frame3d frDest ;
|
|
bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ;
|
|
// ne determino gli spigoli
|
|
ICURVEPOVECTOR vpCurve ;
|
|
bOk = bOk && pStm->GetEdges( vpCurve) ;
|
|
// inserisco gli spigoli come curve nel DB
|
|
int nFirstId = GDB_ID_NULL ;
|
|
int nCount = 0 ;
|
|
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
|
// se richiesto, verifico l'angolo tra le facce adiacenti (0=allineate)
|
|
if ( bSmoothAng) {
|
|
double dAngInt = vpCurve[i]->GetTempParam() ;
|
|
if ( abs( dAngInt) < pStm->GetSmoothAngle())
|
|
continue ;
|
|
}
|
|
// lo porto nel riferimento destinazione
|
|
bOk = bOk && vpCurve[i]->LocToLoc( frSurf, frDest) ;
|
|
// lo inserisco nel DB geometrico
|
|
int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( vpCurve[i])) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nNewId != GDB_ID_NULL) ;
|
|
// copio il materiale
|
|
bOk = bOk && pGeomDB->CopyMaterial( nId, nNewId) ;
|
|
// aggiorno contatori
|
|
if ( bOk && nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
if ( bOk)
|
|
++ nCount ;
|
|
}
|
|
if ( ! bOk)
|
|
nCount = -1 ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfTmGetEdges(" + ToString( nId) + ",{" +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
return nFirstId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfTmGetCurvatures( int nId, int nV, double& dK1, Vector3d& vtK1, double& dK2, Vector3d& vtK2)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
|
|
// Inzializzo i parametri di ritorno
|
|
dK1 = 0. ; dK2 = 0. ;
|
|
vtK1 = V_NULL ; vtK2 = V_NULL ;
|
|
|
|
// Recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
bool bOk = ( pStm != nullptr) ;
|
|
// Recupero il riferimento globale del gruppo cui appartiene
|
|
Frame3d frSurf ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ;
|
|
|
|
// Calcolo la Curvatura
|
|
bool bPlanar = false ;
|
|
Vector3d vtNorm = V_NULL ;
|
|
bOk = bOk && pStm->GetCurvature( nV, dK1, vtK1, dK2, vtK2, bPlanar, vtNorm) ;
|
|
// Se superficie localmente piana
|
|
if ( bPlanar) {
|
|
vtK1 = V_NULL ; // Generico vettore parallelo alla superficie (dK1 circa 0.)
|
|
vtK2 = V_NULL ; // generico vettore generico parallelo alla superficie e perpendicolare a vtK1 (dK2 circa 0.)
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfTmGetCurvature(" + ToString( nId) + "," +
|
|
ToString( nV) + ")" +
|
|
" -- bOk=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
// Restituisco il risultato
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfBezierGetPoint( int nSurfId, double dU, double dV, int nRefId, Point3d& ptP)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie di Bezier
|
|
const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ;
|
|
bool bOk = ( pSbz != nullptr) ;
|
|
// richiedo il punto
|
|
bOk = bOk && pSbz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP) ;
|
|
// gestione trasformazioni ( eventuali)
|
|
bOk = bOk && TransformPoint( pGeomDB, nSurfId, nRefId, ptP) ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfBezierGetPoint(" + ToString( nSurfId) + "," +
|
|
ToString( dU) + "," +
|
|
ToString( dV) + "," +
|
|
ToString( nRefId) + ")" +
|
|
" -- Pnt=" + ( bOk ? "{" + ToString( ptP) + "}" : "nil") ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfBezierGetPointD1( int nSurfId, double dU, double dV, int nUsd, int nVsd, int nRefId,
|
|
Point3d& ptP, Vector3d& vtDerU, Vector3d& vtDerV)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie di Bezier
|
|
const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ;
|
|
bool bOk = ( pSbz != nullptr) ;
|
|
// direzioni di approccio
|
|
ISurfBezier::Side nSbzUsd = ( nUsd > 0 ? ISurfBezier::FROM_PLUS : ISurfBezier::FROM_MINUS) ;
|
|
ISurfBezier::Side nSbzVsd = ( nVsd > 0 ? ISurfBezier::FROM_PLUS : ISurfBezier::FROM_MINUS) ;
|
|
// richiedo il punto
|
|
bOk = bOk && pSbz->GetPointD1D2( dU, dV, nSbzUsd, nSbzVsd, ptP, &vtDerU, &vtDerV) ;
|
|
// gestione trasformazioni ( eventuali)
|
|
bOk = bOk && TransformPoint( pGeomDB, nSurfId, nRefId, ptP) &&
|
|
TransformVector( pGeomDB, nSurfId, nRefId, vtDerU) &&
|
|
TransformVector( pGeomDB, nSurfId, nRefId, vtDerV) ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfBezierGetPointD1(" + ToString( nSurfId) + "," +
|
|
ToString( dU) + "," +
|
|
ToString( dV) + "," +
|
|
ToString( nUsd) + "," +
|
|
ToString( nVsd) + "," +
|
|
ToString( nRefId) + ")" +
|
|
" -- Pnt=" + ( bOk ? "{" + ToString( ptP) + "}" : "nil") +
|
|
" DerU=" + ( bOk ? "{" + ToString( vtDerU) + "}" : "nil") +
|
|
" DerV=" + ( bOk ? "{" + ToString( vtDerV) + "}" : "nil") ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfBezierGetPointNrmD1( int nSurfId, double dU, double dV, int nUsd, int nVsd, int nRefId,
|
|
Point3d& ptP, Vector3d& vtN, Vector3d& vtDerU, Vector3d& vtDerV)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie di Bezier
|
|
const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ;
|
|
bool bOk = ( pSbz != nullptr) ;
|
|
// direzioni di approccio
|
|
ISurfBezier::Side nSbzUsd = ( nUsd > 0 ? ISurfBezier::FROM_PLUS : ISurfBezier::FROM_MINUS) ;
|
|
ISurfBezier::Side nSbzVsd = ( nVsd > 0 ? ISurfBezier::FROM_PLUS : ISurfBezier::FROM_MINUS) ;
|
|
// richiedo il punto
|
|
bOk = bOk && pSbz->GetPointNrmD1D2( dU, dV, nSbzUsd, nSbzVsd, ptP, vtN, &vtDerU, &vtDerV) ;
|
|
// gestione trasformazioni ( eventuali)
|
|
bOk = bOk && TransformPoint( pGeomDB, nSurfId, nRefId, ptP) &&
|
|
TransformVector( pGeomDB, nSurfId, nRefId, vtN) &&
|
|
TransformVector( pGeomDB, nSurfId, nRefId, vtDerU) &&
|
|
TransformVector( pGeomDB, nSurfId, nRefId, vtDerV) ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfBezierGetPointNrmD1(" + ToString( nSurfId) + "," +
|
|
ToString( dU) + "," +
|
|
ToString( dV) + "," +
|
|
ToString( nUsd) + "," +
|
|
ToString( nVsd) + "," +
|
|
ToString( nRefId) + ")" +
|
|
" -- Pnt=" + ( bOk ? "{" + ToString( ptP) + "}" : "nil") +
|
|
" Nrm=" + ( bOk ? "{" + ToString( vtN) + "}" : "nil") +
|
|
" DerU=" + ( bOk ? "{" + ToString( vtDerU) + "}" : "nil") +
|
|
" DerV=" + ( bOk ? "{" + ToString( vtDerV) + "}" : "nil") ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
static int
|
|
MySurfBezierGetCurveUV( int nSurfId, bool bIsU, double dPar, int nDestGrpId)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie di Bezier
|
|
const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ;
|
|
if ( pSbz == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf ;
|
|
if ( ! pGeomDB->GetGlobFrame( nSurfId, frSurf))
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
// richiedo la curva
|
|
PtrOwner<ICurveComposite> pCrv( bIsU ? pSbz->GetCurveOnU( dPar) : pSbz->GetCurveOnV( dPar)) ;
|
|
if ( IsNull( pCrv))
|
|
return GDB_ID_NULL ;
|
|
// se è una curva
|
|
if ( ! pCrv->IsAPoint()) {
|
|
// porto la curva nel riferimento destinazione
|
|
pCrv->LocToLoc( frSurf, frDest) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrv)) ;
|
|
// copio il materiale
|
|
pGeomDB->CopyMaterial( nSurfId, nNewId) ;
|
|
return nNewId ;
|
|
}
|
|
// altrimenti è collassata in un punto
|
|
else {
|
|
Point3d ptP ; pCrv->GetStartPoint( ptP) ;
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
if ( IsNull( pGeoPnt) || ! pGeoPnt->Set( ptP))
|
|
return GDB_ID_NULL ;
|
|
// porto il punto nel riferimento destinazione
|
|
pGeoPnt->LocToLoc( frSurf, frDest) ;
|
|
// lo inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ;
|
|
// copio il materiale
|
|
pGeomDB->CopyMaterial( nSurfId, nNewId) ;
|
|
return nNewId ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeSurfBezierGetCurveU( int nSurfId, double dV, int nDestGrpId)
|
|
{
|
|
// creo la curva
|
|
int nNewId = MySurfBezierGetCurveUV( nSurfId, true, dV, nDestGrpId) ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfBezierGetCurveU(" + ToString( nSurfId) + "," +
|
|
ToString( dV) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id=" + ToString( nNewId) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
return nNewId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeSurfBezierGetCurveV( int nSurfId, double dU, int nDestGrpId)
|
|
{
|
|
// creo la curva
|
|
int nNewId = MySurfBezierGetCurveUV( nSurfId, false, dU, nDestGrpId) ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfBezierGetCurveV(" + ToString( nSurfId) + "," +
|
|
ToString( dU) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id=" + ToString( nNewId) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
return nNewId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfBezierParamsFromPoint( int nSurfId, const Point3d& ptOnSurf, int nRefId, double& dU, double& dV)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie di Bezier
|
|
const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ;
|
|
if ( pSbz == nullptr)
|
|
return false ;
|
|
// porto il punto Near nel riferimento dell'entità
|
|
Point3d ptOnSurfL = ptOnSurf ;
|
|
if ( ! InvTransformPoint( pGeomDB, nSurfId, nRefId, ptOnSurfL))
|
|
return false ;
|
|
// determino i parametri corrispondenti al punto
|
|
Point3d ptParam ;
|
|
if ( ! pSbz->UnprojectPoint( ptOnSurfL, ptParam, P_INVALID))
|
|
return false ;
|
|
dU = ptParam.x ;
|
|
dV = ptParam.y ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfBezierGetInfo( int nSurfId, int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIsRat, bool& bTrimmed)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie di Bezier
|
|
const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ;
|
|
bool bOk = ( pSbz != nullptr) ;
|
|
// recupero le info (gradi in U e V, flag di razionale)
|
|
bOk = bOk && pSbz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bIsRat, bTrimmed) ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfBezierGetInfo(" + ToString( nSurfId) + ")" +
|
|
" -- DegU=" + ( bOk ? ToString( nDegU) : "nil") +
|
|
" -- DegV=" + ( bOk ? ToString( nDegV) : "nil") +
|
|
" -- SpanU=" + ( bOk ? ToString( nSpanU) : "nil") +
|
|
" -- SpanV=" + ( bOk ? ToString( nSpanV) : "nil") +
|
|
" -- IsRat=" + ( bOk ? ToString( bIsRat) : "nil") +
|
|
" -- Trim=" + ( bOk ? ToString( bTrimmed) : "nil") ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
MySurfBezierGetControlCurveUV( int nSurfId, bool bIsU, int nInd, int nDestGrpId)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie di Bezier
|
|
const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ;
|
|
if ( pSbz == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf ;
|
|
if ( ! pGeomDB->GetGlobFrame( nSurfId, frSurf))
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
// richiedo i dati della polilinea
|
|
PolyLine PL ;
|
|
if ( bIsU)
|
|
pSbz->GetControlCurveOnU( nInd, PL) ;
|
|
else
|
|
pSbz->GetControlCurveOnV( nInd, PL) ;
|
|
// se è una curva
|
|
if ( PL.GetPointNbr() > 1) {
|
|
PtrOwner<ICurveComposite> pCrvCo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvCo) || ! pCrvCo->FromPolyLine( PL))
|
|
return GDB_ID_NULL ;
|
|
// porto la curva nel riferimento destinazione
|
|
pCrvCo->LocToLoc( frSurf, frDest) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCo)) ;
|
|
// copio il materiale
|
|
pGeomDB->CopyMaterial( nSurfId, nNewId) ;
|
|
return nNewId ;
|
|
}
|
|
// se altrimenti è collassata in un punto
|
|
else if ( PL.GetPointNbr() == 1) {
|
|
Point3d ptP ; PL.GetFirstPoint( ptP) ;
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
if ( IsNull( pGeoPnt) || ! pGeoPnt->Set( ptP))
|
|
return GDB_ID_NULL ;
|
|
// porto il punto nel riferimento destinazione
|
|
pGeoPnt->LocToLoc( frSurf, frDest) ;
|
|
// lo inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ;
|
|
// copio il materiale
|
|
pGeomDB->CopyMaterial( nSurfId, nNewId) ;
|
|
return nNewId ;
|
|
}
|
|
// altrimenti è errore
|
|
else
|
|
return GDB_ID_NULL ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeSurfBezierGetControlCurveU( int nSurfId, int nIndV, int nDestGrpId)
|
|
{
|
|
// creo la curva
|
|
int nNewId = MySurfBezierGetControlCurveUV( nSurfId, true, nIndV, nDestGrpId) ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfBezierGetControlCurveU(" + ToString( nSurfId) + "," +
|
|
ToString( nIndV) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id=" + ToString( nNewId) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
return nNewId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeSurfBezierGetControlCurveV( int nSurfId, int nIndU, int nDestGrpId)
|
|
{
|
|
// creo la curva
|
|
int nNewId = MySurfBezierGetControlCurveUV( nSurfId, false, nIndU, nDestGrpId) ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfBezierGetControlCurveV(" + ToString( nSurfId) + "," +
|
|
ToString( nIndU) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id=" + ToString( nNewId) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
return nNewId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeExtractSurfBezierLoops( int nId, int nDestGrpId, int* pnCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie di Bezier
|
|
const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nId)) ;
|
|
bool bOk = ( pSbz != nullptr) ;
|
|
if ( ! bOk)
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ;
|
|
// recupero il riferimento di destinazione
|
|
Frame3d frDest ;
|
|
bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ;
|
|
// richiedo i contorni della superficie e li inserisco nel DB
|
|
int nFirstId = GDB_ID_NULL ;
|
|
int nCount = 0 ;
|
|
ICRVCOMPOPOVECTOR vCC ;
|
|
pSbz->GetLoops( vCC, true) ;
|
|
for ( int i = 0 ; i < int( vCC.size()) ; ++i) {
|
|
if ( IsNull( vCC[i]) || ! vCC[i]->IsValid())
|
|
continue ;
|
|
// porto la curva nel riferimento destinazione
|
|
bOk = bOk && vCC[i]->LocToLoc(frSurf, frDest) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( vCC[i])) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nNewId != GDB_ID_NULL) ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( bOk && nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
if ( bOk)
|
|
++ nCount ;
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtExtractSurfBezierLoops(" + ToString( nId) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
return nFirstId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExeShowSurfBezierControlPoints( int nSrfId, int nDestGrpId, int* pnCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie di bezier
|
|
IGeoObj* pGeoObj = pGeomDB->GetGeoObj( nSrfId) ;
|
|
if ( pGeoObj == nullptr || pGeoObj->GetType() != SRF_BEZIER)
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento della superficie
|
|
Frame3d frSurf ;
|
|
bool bOk = true ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nSrfId, frSurf) ;
|
|
// recupero il riferimento di destinazione
|
|
Frame3d frDest ;
|
|
bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ;
|
|
if ( ! bOk)
|
|
return GDB_ID_NULL ;
|
|
int nDegU = - 1, nDegV = - 1, nSpanU = - 1, nSpanV = - 1 ;
|
|
bool bRat = false, bTrimmed = false ;
|
|
ISurfBezier* pSrfBez = GetSurfBezier( pGeoObj) ;
|
|
pSrfBez->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ;
|
|
int nFirstId = -1 ;
|
|
int nCount = 0 ;
|
|
for ( int i = 0 ; i < (nDegU * nSpanU + 1) * ( nDegV * nSpanV + 1) ; ++i) {
|
|
IGeoPoint3d* pGeoPt( CreateGeoPoint3d()) ;
|
|
pGeoPt->Set( pSrfBez->GetControlPoint( i, &bOk)) ;
|
|
pGeoPt->LocToLoc( frSurf, frDest) ;
|
|
int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, pGeoPt) ;
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nId ;
|
|
if ( nId != GDB_ID_NULL)
|
|
++nCount ;
|
|
}
|
|
// restituisco i risultati
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
return nFirstId ;
|
|
}
|