eacbbc1c1f
- aggiunte funzioni Exe e Lua GetSurfTmPlaneInters.
834 lines
33 KiB
C++
834 lines
33 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2015
|
|
//----------------------------------------------------------------------------
|
|
// File : EXE_ModifySurf.cpp Data : 04.05.15 Versione : 1.6e1
|
|
// Contenuto : Funzioni di modifica delle superfici per EXE.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 09.03.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "EXE.h"
|
|
#include "EXE_Macro.h"
|
|
#include "EXE_Const.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/EGkCurveLine.h"
|
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
|
|
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
|
#include "/EgtDev/Include/EGkSurfLocal.h"
|
|
#include "/EgtDev/Include/EgkChainCurves.h"
|
|
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
|
#include "/EgtDev/Include/EGkCDSimpleSurfFrMove.h"
|
|
#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h"
|
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeInvertSurface( const INTVECTOR& vIds)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// eseguo inversione
|
|
bool bOk = true ;
|
|
for ( size_t i = 0 ; i < vIds.size() && bOk ; ++ i) {
|
|
int nId = (( vIds[i] != GDB_ID_SEL) ? vIds[i] : pGeomDB->GetFirstSelectedObj()) ;
|
|
while ( nId != GDB_ID_NULL && bOk) {
|
|
// recupero la superficie e la inverto
|
|
ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pSurf != nullptr && ! pSurf->Invert())
|
|
bOk = false ;
|
|
// passo alla successiva
|
|
nId = (( vIds[i] != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ;
|
|
}
|
|
}
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtInvertSurf({" + IdListToString( vIds) + "})" +
|
|
" -- Ok=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultato
|
|
return bOk ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static int
|
|
MyExplodeSurfTriMesh( int nId, int* pnCount)
|
|
{
|
|
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 numero di facce
|
|
int nFacet = pStm->GetFacetCount() ;
|
|
// se c'è una sola faccia, non devo fare alcunché
|
|
if ( nFacet == 1) {
|
|
if ( pnCount != nullptr)
|
|
*pnCount = 1 ;
|
|
return nId ;
|
|
}
|
|
// copio tutte le facce
|
|
int nFirstId = GDB_ID_NULL ;
|
|
int nCount = 0 ;
|
|
for ( int i = 0 ; i < nFacet ; ++ i) {
|
|
ISurfTriMesh* pFac = pStm->CloneFacet( i) ;
|
|
if ( pFac == nullptr)
|
|
continue ;
|
|
// inserisco la superficie nello stesso gruppo e nello stesso posto del GeomDB
|
|
int nFacId = pGeomDB->InsertGeoObj( GDB_ID_NULL, nId, GDB_BEFORE, pFac) ;
|
|
if ( nFacId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// copio gli attributi
|
|
if ( ! pGeomDB->CopyAttributes( nId, nFacId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nFacId ;
|
|
++ nCount ;
|
|
}
|
|
// elimino la superficie originale
|
|
pGeomDB->Erase( nId) ;
|
|
// restituisco risultati
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static int
|
|
MyExplodeSurfFlatRegion( int nId, int* pnCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie FlatRegion
|
|
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pSfr == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// recupero il numero di componenti connessi (chunk)
|
|
int nChunk = pSfr->GetChunkCount() ;
|
|
// se c'è un solo componente, non devo fare alcunché
|
|
if ( nChunk == 1) {
|
|
if ( pnCount != nullptr)
|
|
*pnCount = 1 ;
|
|
return nId ;
|
|
}
|
|
// copio tutti i componenti connessi (chunk)
|
|
int nFirstId = GDB_ID_NULL ;
|
|
int nCount = 0 ;
|
|
for ( int i = 0 ; i < nChunk ; ++ i) {
|
|
ISurfFlatRegion* pChk = pSfr->CloneChunk( i) ;
|
|
if ( pChk == nullptr)
|
|
continue ;
|
|
// inserisco la superficie nello stesso gruppo e nello stesso posto del GeomDB
|
|
int nNewId = pGeomDB->InsertGeoObj( GDB_ID_NULL, nId, GDB_BEFORE, pChk) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// copio gli attributi
|
|
if ( ! pGeomDB->CopyAttributes( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nCount ;
|
|
}
|
|
// elimino la superficie
|
|
pGeomDB->Erase( nId) ;
|
|
// restituisco risultati
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
ExeExplodeSurface( int nId, int* pnCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero il tipo di superficie
|
|
int nFirstId = GDB_ID_NULL ;
|
|
int nCount = 0 ;
|
|
switch ( pGeomDB->GetGeoType( nId)) {
|
|
case SRF_TRIMESH :
|
|
nFirstId = MyExplodeSurfTriMesh( nId, &nCount) ;
|
|
break ;
|
|
case SRF_FLATRGN :
|
|
nFirstId = MyExplodeSurfFlatRegion( nId, &nCount) ;
|
|
break ;
|
|
}
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtExplodeSurf(" + ToString( nId) + ")" +
|
|
" -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultati
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
return nFirstId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfFrAdd( int nId1, int nId2)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// 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 in locale alla prima
|
|
SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ;
|
|
const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ;
|
|
bOk = bOk && ( pSfr2L != nullptr) ;
|
|
// eseguo l'unione tra le due superfici
|
|
bOk = bOk && pSfr1->Add( *pSfr2L) ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfFrAdd(" + ToString( nId1) + "," +
|
|
ToString( nId2) + ")" +
|
|
" -- Ok=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfFrSubtract( int nId1, int nId2)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// 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 in locale alla prima
|
|
SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ;
|
|
const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ;
|
|
bOk = bOk && ( pSfr2L != nullptr) ;
|
|
// eseguo la sottrazione della seconda superficie dalla prima
|
|
bOk = bOk && pSfr1->Subtract( *pSfr2L) ;
|
|
// se il risultato è vuoto, cancello la FlatRegion
|
|
if ( bOk && ! pSfr1->IsValid())
|
|
pGeomDB->Erase( nId1) ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfFrSubtract(" + ToString( nId1) + "," +
|
|
ToString( nId2) + ")" +
|
|
" -- Ok=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfFrIntersect( int nId1, int nId2)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// 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 in locale alla prima
|
|
SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ;
|
|
const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ;
|
|
bOk = bOk && ( pSfr2L != nullptr) ;
|
|
// eseguo l'intersezione tra le due superfici
|
|
bOk = bOk && pSfr1->Intersect( *pSfr2L) ;
|
|
// se il risultato è vuoto, cancello la FlatRegion
|
|
if ( bOk && ! pSfr1->IsValid())
|
|
pGeomDB->Erase( nId1) ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfFrIntersect(" + ToString( nId1) + "," +
|
|
ToString( nId2) + ")" +
|
|
" -- Ok=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfFrOffset( int nId, double dDist, int nType)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie FlatRegion
|
|
ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
|
|
bool bOk = ( pSfr != nullptr) ;
|
|
// eseguo l'offset
|
|
bOk = bOk && pSfr->Offset( dDist, nType) ;
|
|
// se il risultato è vuoto, cancello la FlatRegion
|
|
if ( bOk && ! pSfr->IsValid())
|
|
pGeomDB->Erase( nId) ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfFrOffset(" + ToString( nId) + "," +
|
|
ToString( dDist) + "," +
|
|
ToString( nType) + ")" +
|
|
" -- Ok=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
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 ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfFrMoveSimpleNoCollision( int nId1, int nId2, const Vector3d& vtDir, double& dLen, int nRefType)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// 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 in locale alla prima
|
|
SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ;
|
|
const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ;
|
|
bOk = bOk && ( pSfr2L != nullptr) ;
|
|
// porto in locale alla prima superficie il versore di movimento
|
|
Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frSurf1) ;
|
|
// calcolo massima lunghezza di traslazione della prima regione senza semplice collisione con la seconda
|
|
return ( bOk && CDSimpleSurfFrMove( *pSfr1, *pSfr2L).Translate( vtDirL, dLen)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ExeSurfFrRotateSimpleNoCollision( int nId1, int nId2, const Point3d& ptCen, double& dAngDeg, int nRefType)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// 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 in locale alla prima
|
|
SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ;
|
|
const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ;
|
|
bOk = bOk && ( pSfr2L != nullptr) ;
|
|
// porto in locale alla prima superficie il versore di movimento
|
|
Point3d ptCenL = GetPointLocal( pGeomDB, ptCen, nRefType, frSurf1) ;
|
|
// calcolo massimo angolo di rotazione della prima regione senza semplice collisione con la seconda
|
|
return ( bOk && CDSimpleSurfFrMove( *pSfr1, *pSfr2L).Rotate(ptCenL, dAngDeg)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
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, int nDestGrpId, int nRefType, 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) ;
|
|
// 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, 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 = "EgtGetSurfTmSilhouette(" + ToString( nId) + ",{" +
|
|
ToString( vtDir) + "}," +
|
|
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 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]) ;
|
|
// 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
|
|
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 ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static int
|
|
MyGetSurfTmPlaneInters( int nId, const Point3d& ptOn, const Vector3d& vtN, int nDestGrpId, int nRefType,
|
|
int* pnPntCount, int* pnCrvCount, int* pnSrfCount)
|
|
{
|
|
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 ;
|
|
// porto in locale il punto e la normale del piano
|
|
Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frSurf) ;
|
|
Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frSurf) ;
|
|
// calcolo il piano di intersezione
|
|
Plane3d plPlane ;
|
|
if ( ! plPlane.Set( ptOnL, vtNL))
|
|
return GDB_ID_NULL ;
|
|
// eseguo l'intersezione
|
|
PNTVECTOR vPnt ;
|
|
BIPNTVECTOR vBpt ;
|
|
TRIA3DVECTOR vTria ;
|
|
if ( ! IntersPlaneSurfTm( plPlane, *pStm, vPnt, vBpt, vTria))
|
|
return GDB_ID_NULL ;
|
|
// Inserisco il risultato nel DB
|
|
int nFirstId = GDB_ID_NULL ;
|
|
int nPntCount = 0 ;
|
|
int nCrvCount = 0 ;
|
|
int nSrfCount = 0 ;
|
|
// Inserisco i punti nel DB
|
|
for ( size_t i = 0 ; i < vPnt.size() ; ++ i) {
|
|
// creo il punto
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
if ( ! IsNull( pGeoPnt))
|
|
return GDB_ID_NULL ;
|
|
// setto il punto
|
|
pGeoPnt->Set( vPnt[i]) ;
|
|
// 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)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nPntCount ;
|
|
}
|
|
// Concateno i tratti di curva
|
|
double dToler = 20 * EPS_SMALL ;
|
|
ChainCurves chainC ;
|
|
chainC.Init( false, dToler, int( vBpt.size())) ;
|
|
for ( size_t i = 0 ; i < vBpt.size() ; ++ i) {
|
|
Vector3d vtDir = vBpt[i].second - vBpt[i].first ;
|
|
vtDir.Normalize() ;
|
|
if ( ! chainC.AddCurve( int( i) + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir))
|
|
return GDB_ID_NULL ;
|
|
}
|
|
// recupero i percorsi concatenati
|
|
Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ;
|
|
INTVECTOR vId ;
|
|
while ( chainC.GetChainFromNear( ptNear, false, vId)) {
|
|
// creo una curva composita
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvCompo))
|
|
return GDB_ID_NULL ;
|
|
// recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita
|
|
for ( size_t i = 0 ; i < vId.size() ; ++ i) {
|
|
// creo una segmento di retta
|
|
int nInd = vId[i] - 1 ;
|
|
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
|
if ( IsNull( pLine) || ! pLine->Set( vBpt[nInd].first, vBpt[nInd].second))
|
|
return GDB_ID_NULL ;
|
|
// lo accodo alla composita
|
|
if ( ! pCrvCompo->AddCurve( Release( pLine), true, dToler))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno il prossimo near
|
|
ptNear = vBpt[nInd].second ;
|
|
}
|
|
// se lunghezza curva inferiore a 5 volte la tolleranza, la salto
|
|
double dCrvLen ;
|
|
if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5. * dToler)
|
|
continue ;
|
|
// se curva chiusa entro 5 volte la tolleranza ma considerata aperta, la chiudo bene
|
|
Point3d ptStart, ptEnd ;
|
|
if ( pCrvCompo->GetStartPoint( ptStart) &&
|
|
pCrvCompo->GetEndPoint( ptEnd) &&
|
|
AreSamePointEpsilon( ptStart, ptEnd, 5. * dToler) &&
|
|
! AreSamePointApprox( ptStart, ptEnd)) {
|
|
// porto il punto finale a coincidere esattamente con l'inizio
|
|
pCrvCompo->ModifyEnd( ptStart) ;
|
|
}
|
|
// assegno estrusione come direzione normale al piano
|
|
pCrvCompo->SetExtrusion( plPlane.GetVersN()) ;
|
|
// unisco segmenti allineati
|
|
pCrvCompo->MergeCurves( 0.5 * dToler, ANG_TOL_STD_DEG) ;
|
|
// porto la curva 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( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nCrvCount ;
|
|
}
|
|
// Costruisco una superficie trimesh dall'insieme di triangoli
|
|
StmFromTriangleSoup StmFts ;
|
|
if ( ! StmFts.Start())
|
|
return GDB_ID_NULL ;
|
|
for ( size_t i = 0 ; i < vTria.size() ; ++ i)
|
|
// inserisco il triangolo nella nuova superficie
|
|
StmFts.AddTriangle( vTria[i]) ;
|
|
// valido la superficie e calcolo le adiacenze
|
|
if ( ! StmFts.End())
|
|
return GDB_ID_NULL ;
|
|
// se superficie con triangoli
|
|
PtrOwner<ISurfTriMesh> pNewStm( StmFts.GetSurf()) ;
|
|
if ( ! IsNull( pNewStm) && pNewStm->GetTriangleCount() > 0) {
|
|
// porto la superficie nel riferimento destinazione
|
|
pNewStm->LocToLoc( frSurf, frDest) ;
|
|
// la inserisco nel DB
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pNewStm)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nSrfCount ;
|
|
}
|
|
// aggiorno contatori
|
|
if ( pnPntCount != nullptr)
|
|
*pnPntCount = nPntCount ;
|
|
if ( pnCrvCount != nullptr)
|
|
*pnCrvCount = nCrvCount ;
|
|
if ( pnSrfCount != nullptr)
|
|
*pnSrfCount = nSrfCount ;
|
|
// restituisco l'identificativo della prima nuova entità
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
ExeGetSurfTmPlaneInters( int nId, const Point3d& ptOn, const Vector3d& vtN, int nDestGrpId, int nRefType,
|
|
int* pnPntCount, int* pnCrvCount, int* pnSrfCount)
|
|
{
|
|
// eseguo
|
|
int nPntCount = 0 ;
|
|
int nCrvCount = 0 ;
|
|
int nSrfCount = 0 ;
|
|
int nFirstId = MyGetSurfTmPlaneInters( nId, ptOn, vtN, nDestGrpId, nRefType, &nPntCount, &nCrvCount, &nSrfCount) ;
|
|
// aggiorno contatori
|
|
if ( pnPntCount != nullptr)
|
|
*pnPntCount = nPntCount ;
|
|
if ( pnCrvCount != nullptr)
|
|
*pnCrvCount = nCrvCount ;
|
|
if ( pnSrfCount != nullptr)
|
|
*pnSrfCount = nSrfCount ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtGetSurfTmPlaneInters(" + ToString( nId) + ",{" +
|
|
ToString( ptOn) + "},{" +
|
|
ToString( vtN) + "}," +
|
|
ToString( nDestGrpId) + "," +
|
|
RefTypeToString( nRefType) + ")" +
|
|
" -- Id1=" + ToString( nFirstId) + ", PntNbr=" + ToString( nPntCount) +
|
|
", CrvNbr=" + ToString( nCrvCount) + ", SrfNbr=" + ToString( nSrfCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco l'identificativo della prima nuova entità
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
bool
|
|
ExeCutSurfTm( int nId, const Point3d& ptOn, const Vector3d& vtN, bool bSaveOnEq, int nRefType)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie TriMesh
|
|
ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
bool bOk = ( pStm != nullptr) ;
|
|
// recupero il riferimento locale
|
|
Frame3d frLoc ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ;
|
|
// porto in locale il punto e la normale del piano
|
|
Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frLoc) ;
|
|
Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frLoc) ;
|
|
// calcolo il piano di taglio
|
|
Plane3d plPlane ;
|
|
bOk = bOk && plPlane.Set( ptOnL, vtNL) ;
|
|
// eseguo il taglio
|
|
bOk = bOk && pStm->Cut( plPlane, bSaveOnEq) ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtCutSurfTm(" + ToString( nId) + ",{" +
|
|
ToString( ptOn) + "},{" +
|
|
ToString( vtN) + "}," +
|
|
RefTypeToString( nRefType) + ")" +
|
|
" -- Ok=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco risultato
|
|
return bOk ;
|
|
}
|