Files
EgtExecutor/EXE_GdbGetSurf.cpp
DarioS 90449cad40 EgtExecutor 2.5g1 :
- aggiunte funzioni Exe e Lua SurfTmVertexCount, SurfTmGetVertex, SurfTmGetNearestVertex, SurfTmGetAllVertInFacet e SurfTmMoveVertex.
2023-07-07 17:07:16 +02:00

1416 lines
55 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/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/EGkDistPointSurfTm.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)
// verifico il parametro
if ( &dArea == nullptr)
return 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)
// verifico il parametro
if ( &dVol == nullptr)
return 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)
// verifico il parametro
if ( &dArea == nullptr)
return 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, GDB_ID_NULL)
// recupero la prima superficie FlatRegion
ISurfFlatRegion* pSfr1 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId1)) ;
if ( pSfr1 == nullptr)
return false ;
// se richiesta distanza di sicurezza, ne faccio l'offset
PtrOwner<ISurfFlatRegion> pSfr1O( pSfr1->Clone()) ;
if ( IsNull( pSfr1O))
return false ;
if ( dMinDist > 10 * EPS_SMALL)
pSfr1O->Offset( dMinDist, ICurve::OFF_FILLET) ;
// 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 < pSfr1O->GetChunkCount() ; ++ i) {
for ( int j = 0 ; j < pSfr2L->GetChunkCount() ; ++ j) {
if ( pSfr1O->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 < pSfr1O->GetChunkCount() ; ++ i) {
PtrOwner<ICurve> pCrv1( pSfr1O->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_NULL)
return false ;
}
}
return true ;
}
// se altrimenti punto
else if ( nType2 == GEO_PNT3D) {
// recupero il punto
IGeoPoint3d* pGeoPt = GetGeoPoint3d( pGeomDB->GetGeoObj( nId2)) ;
Point3d pt = pGeoPt->GetPoint() ;
// porto il punto in locale
Frame3d frPt ;
if ( ! pGeomDB->GetGlobFrame( nId2, frPt))
return false ;
pt.LocToLoc( frPt, frSurf1) ;
for ( int i = 0 ; i < pSfr1O->GetChunkCount() ; i ++) {
// verifico se è contenuto nel loop esterno
PtrOwner<ICurve> pCrv( pSfr1O->GetLoop( i, 0)) ;
PolyLine PL ;
pCrv->ApproxWithLines( 10 * EPS_SMALL, 15, ICurve::APL_STD, PL) ;
if ( IsPointInsidePolyLine( pt, PL, EPS_SMALL)) {
bool bInsideHole = false ;
// verifico se è contenuto in un loop interno
for ( int j = 1 ; j < pSfr1O->GetLoopCount( i) ; j ++) {
PtrOwner<ICurve> pCrv( pSfr1O->GetLoop( i, j)) ;
pCrv->ApproxWithLines( 10 * EPS_SMALL, 15, ICurve::APL_STD, PL) ;
PL.Invert() ;
if ( IsPointInsidePolyLine( pt, PL, EPS_SMALL))
bInsideHole = true ;
}
// se è contenuto nel loop esterno ma non è contenuto in nessuno dei loop interni allora il punto è interno
if ( ! bInsideHole)
return false ;
}
}
return true ;
}
// 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() ;
}
//----------------------------------------------------------------------------
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 ;
}
//----------------------------------------------------------------------------
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
ExeSurfFrGetZigZagInfill( int nId, int nDestGrpId, double dStep, double dAng, bool bStepCorrection, bool bInvert, int* pnCount)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
// recupero la superficie FlatRegion
ISurfFlatRegion * pOrigSrf = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
if ( pOrigSrf == nullptr)
return GDB_ID_NULL ;
PtrOwner<ISurfFlatRegion> pSfr( pOrigSrf->Clone()) ;
bool bOk = ( ! IsNull( pSfr)) ;
// 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) ;
// creo il riferimento per il calcolo del percorso a zigzag
Vector3d vtN ;
if ( bOk)
vtN = pSfr->GetNormVersor() ;
bOk = bOk && vtN.ToGlob( frSurf) ;
Frame3d frRef ;
bOk = bOk && frRef.Set( ORIG, vtN) ;
bOk = bOk && frRef.Rotate( ORIG, vtN, dAng) ;
// calcolo il percorso a zigzag
bOk = bOk && pSfr->LocToLoc( frSurf, frRef) ;
ICRVCOMPOPOVECTOR vpCrvs ;
bOk = bOk && pSfr->GetZigZagInfill( dStep, bStepCorrection, bInvert, vpCrvs) ;
// inserisco le curve risultanti nel DB
int nFirstId = GDB_ID_NULL ;
int nCount = 0 ;
for ( int i = 0 ; bOk && i < ( int) vpCrvs.size() ; i ++) {
// porto la curva nel riferimento di destinazione
bOk = bOk && vpCrvs[i]->LocToLoc( frRef, frDest) ;
// la inserisco nel DB geometrico
int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( vpCrvs[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() ;
// 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
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) ;
}
//----------------------------------------------------------------------------
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
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)
{
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) ;
// 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 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
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 ( nId != GDB_ID_ROOT && ! pGeomDB->GetGroupGlobFrame( pGeomDB->GetParentId( 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 ( nId != GDB_ID_ROOT && ! pGeomDB->GetGroupGlobFrame( pGeomDB->GetParentId( 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
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 ;
}
//----------------------------------------------------------------------------
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
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) ;
// 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 ;
int nL = 0 ;
PtrOwner<ICurve> pCrv( bOk ? pSbz->GetLoop( 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 ? pSbz->GetLoop( ++nL) : nullptr) ;
}
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 ;
}