60e7f9040a
- aggiunto check per la scelta del lato a cui appliare l'interpolazione delle direzioni di lavorazione - corretta gestione delle direzioni rispetto al bordo scelto per l'operazione di interpolazione.
1463 lines
65 KiB
C++
1463 lines
65 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2025-2025
|
|
//----------------------------------------------------------------------------
|
|
// File : EXE_Trimming.cpp Data : 25.10.25 Versione : 2.7j3
|
|
// Funzioni per le lavorazioni di Trimming.
|
|
//
|
|
// Modifiche : 23.10.25 RE Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "EXE.h"
|
|
#include "EXE_Macro.h"
|
|
#include "DllExchange.h"
|
|
#include "GeoTools.h"
|
|
#include "AuxTools.h"
|
|
#include "/EgtDev/Include/EGkGeoVector3d.h"
|
|
#include "/EgtDev/Include/EGkCurveAux.h"
|
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
|
#include "/EgtDev/Include/EXeExecutor.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
#include "/EgtDev/Include/EGkSurfLocal.h"
|
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkTrimming.h"
|
|
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
|
#include "/EgtDev/Include/EGkDistPointSurfBz.h"
|
|
#include "/EgtDev/Include/EGkSbzFromCurves.h"
|
|
#include <unordered_map>
|
|
#include <algorithm>
|
|
|
|
|
|
using namespace std ;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
bool
|
|
ExeTrimmingGetHoleBorder( int nParentId, const INTVECTOR& vSurfIds, const INTVECTOR& vOtherSurfIds,
|
|
double dSurfLinTol, double dSurfAngTol, double dEdgeLinTol, double dEdgeAngTol,
|
|
double dEdgeThick, int& nFirstId, int& nCount)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
|
|
// Inizializzo i valori di ritorno
|
|
nFirstId = GDB_ID_NULL ;
|
|
nCount = 0 ;
|
|
|
|
// Se non ho geometrie da ricercare, non faccio nulla
|
|
if ( vSurfIds.empty())
|
|
return true ;
|
|
|
|
// Recupero le superfici da cui estrarre i bordi
|
|
CISURFPVECTOR vpSurfs ; vpSurfs.reserve( vSurfIds.size()) ;
|
|
for ( int i = 0 ; i < ssize( vSurfIds) ; ++ i) {
|
|
int nSurfId = vSurfIds[i] ;
|
|
// Recupero l'entità
|
|
const IGeoObj* pGeoObj = pGeomDB->GetGeoObj( nSurfId) ;
|
|
if ( pGeoObj != nullptr) {
|
|
// Recupero il Tipo
|
|
int nType = pGeoObj->GetType() ;
|
|
if ( nType == SRF_TRIMESH || nType == SRF_BEZIER) {
|
|
// Recupero la superficie
|
|
const ISurf* pSurf = GetSurf( pGeoObj) ;
|
|
if ( pSurf != nullptr && pSurf->IsValid())
|
|
vpSurfs.emplace_back( pSurf) ;
|
|
}
|
|
}
|
|
}
|
|
// Se non ho superfici non faccio nulla
|
|
if ( vpSurfs.empty())
|
|
return false ;
|
|
|
|
// Calcolo il Centroide delle superfici complessive
|
|
Point3d ptRef = P_INVALID ;
|
|
if ( ! vOtherSurfIds.empty()) {
|
|
int nToTSurf = 0 ;
|
|
for ( int nOtherSurfId : vOtherSurfIds) {
|
|
// Recupero l'entità
|
|
const IGeoObj* pGeoObj = pGeomDB->GetGeoObj( nOtherSurfId) ;
|
|
if ( pGeoObj != nullptr) {
|
|
// Recupero il Tipo
|
|
int nType = pGeoObj->GetType() ;
|
|
if ( nType == SRF_TRIMESH || nType == SRF_BEZIER) {
|
|
// Recupero la superficie
|
|
const ISurf* pSurf = GetSurf( pGeoObj) ;
|
|
if ( pSurf != nullptr && pSurf->IsValid()) {
|
|
// Recupero il Centroide
|
|
Point3d ptCentroid ;
|
|
pSurf->GetCentroid( ptCentroid) ;
|
|
if ( ! ptRef.IsValid())
|
|
ptRef = ptCentroid ;
|
|
else
|
|
ptRef += ptCentroid ;
|
|
++ nToTSurf ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ( nToTSurf > 0) {
|
|
for ( const ISurf* pSurf : vpSurfs) {
|
|
Point3d ptCentroid ;
|
|
pSurf->GetCentroid( ptCentroid) ;
|
|
if ( ! ptRef.IsValid())
|
|
ptRef = ptCentroid ;
|
|
else
|
|
ptRef += ptCentroid ;
|
|
++ nToTSurf ;
|
|
}
|
|
ptRef /= nToTSurf ;
|
|
}
|
|
}
|
|
|
|
// Recupero i Bordi per fori ed asole
|
|
ICRVCOMPOPOVECTOR vHoleBorders ;
|
|
bool bOk = GetTrimmingHoleBorders( vpSurfs, ptRef, dSurfLinTol, dSurfAngTol, dEdgeLinTol, dEdgeAngTol,
|
|
dEdgeThick, vHoleBorders) ;
|
|
if ( bOk) {
|
|
// Inserisco le curve nel DB e imposto i parametri di ritorno
|
|
bool bFirst = true ;
|
|
for ( int i = 0 ; bOk && i < ssize( vHoleBorders) ; ++ i) {
|
|
// Verifico che sia valida
|
|
if ( ! IsNull( vHoleBorders[i]) && vHoleBorders[i]->IsValid()) {
|
|
int nCrvId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( vHoleBorders[i])) ;
|
|
bOk = ( nCrvId != GDB_ID_NULL) ;
|
|
if ( bOk) {
|
|
++ nCount ;
|
|
if ( bFirst) {
|
|
nFirstId = nCrvId ;
|
|
bFirst = false ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtTrimmingGetHoleBorder(" + ToString( nParentId) + "," +
|
|
ToString( vSurfIds) + "," +
|
|
ToString( dSurfLinTol) + "," +
|
|
ToString( dSurfAngTol) + "," +
|
|
ToString( dEdgeLinTol) + "," +
|
|
ToString( dEdgeAngTol) + "," +
|
|
ToString( dEdgeThick) + ")" +
|
|
" bOk=" + ToString( bOk) +
|
|
" nNewSurfId=" + ToString( nFirstId) + ", nCount= " + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
int
|
|
ExeTrimmingGetSurfTmFaceAdj( int nParentId, int nSurfId, int nTria, const Point3d& ptTria,
|
|
double dAngTol, double dSize, double dSizeTol)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
|
|
// Recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nSurfId)) ;
|
|
bool bOk = ( pStm != nullptr && pStm->IsValid()) ;
|
|
|
|
// Recupero la superficie formata dai triangoli di adiacenza
|
|
int nNewSurfId = GDB_ID_NULL ;
|
|
if ( bOk) {
|
|
PtrOwner<ISurfTriMesh> pStmAdjFace( CreateSurfTriMesh()) ;
|
|
bOk = ( ! IsNull( pStmAdjFace) && pStmAdjFace->AdjustTopology()) ;
|
|
bOk = GetTrimmingStmAdjTria( pStm, nTria, ptTria, dAngTol, dSize, dSizeTol, pStmAdjFace) ;
|
|
bOk = ( ! IsNull( pStmAdjFace) && pStmAdjFace->IsValid() && pStmAdjFace->GetTriangleCount() > 0) ;
|
|
// Inserisco la Superficie nel DB geometrico
|
|
if ( bOk) {
|
|
nNewSurfId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStmAdjFace)) ;
|
|
bOk = ( nNewSurfId != GDB_ID_NULL) ;
|
|
}
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtTrimmingGetSurfTmFromFaceAdj(" + ToString( nParentId) + "," +
|
|
ToString( nSurfId) + "," +
|
|
ToString( nTria) + "," +
|
|
"{ " + ToString( ptTria.x) + "," +
|
|
ToString( ptTria.y) + "," +
|
|
ToString( ptTria.z) + "}," +
|
|
ToString( dAngTol) + ")" +
|
|
" nNewSurfId=" + ToString( nNewSurfId) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
return nNewSurfId ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
int
|
|
ExeTrimmingGetSurfTmFromStmFaces( int nParentId, int nSurfId, const INTVECTOR& vFaces)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
|
|
// Recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGlobFrame( nParentId, frDest))
|
|
return GDB_ID_NULL ;
|
|
|
|
// Recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nSurfId)) ;
|
|
if ( pStm == nullptr || ! pStm->IsValid())
|
|
return GDB_ID_NULL ;
|
|
|
|
// Verifico che le facce appartengano alla superficie
|
|
if ( vFaces.empty())
|
|
return CMD_ID_NULL ;
|
|
for ( int nF = 0 ; nF < int( vFaces.size()) ; ++ nF) {
|
|
double dArea = 0. ;
|
|
if ( ! pStm->GetFacetArea( vFaces[nF], dArea))
|
|
return GDB_ID_NULL ;
|
|
}
|
|
|
|
// Definisco la superficie
|
|
StmFromTriangleSoup TriaSoup ;
|
|
TriaSoup.Start() ;
|
|
for ( int nF = 0 ; nF < int( vFaces.size()) ; ++ nF) {
|
|
INTVECTOR vT ;
|
|
if ( ! pStm->GetAllTriaInFacet( vFaces[nF], vT))
|
|
return GDB_ID_NULL ;
|
|
for ( int nT = 0 ; nT < int( vT.size()) ; ++ nT) {
|
|
Triangle3d Tria ;
|
|
if ( ! pStm->GetTriangle( vT[nT], Tria) || ! TriaSoup.AddTriangle( Tria))
|
|
return GDB_ID_NULL ;
|
|
}
|
|
}
|
|
TriaSoup.End() ;
|
|
PtrOwner<ISurfTriMesh> pStmTria( TriaSoup.GetSurf()) ;
|
|
if ( IsNull( pStmTria) || ! pStmTria->IsValid() || pStmTria->GetTriangleCount() == 0)
|
|
return GDB_ID_NULL ;
|
|
|
|
// Aggiungo la superficie al DB
|
|
int nNewSurfId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStmTria)) ;
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "TrimmingGetSurfTmFromStmFaces(" + ToString( nParentId) + "," +
|
|
ToString( nSurfId) + "," +
|
|
ToString( vFaces) + ")" +
|
|
" -- nId=" + ToString( nNewSurfId) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
return nNewSurfId ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
bool
|
|
ExeTrimmingGetAdjSurfs( const INTVECTOR& vSurfId, const INTVECTOR& vOtherSurfId, double dLinTol,
|
|
double dAngTol, double dAngFaceTol, INTVECTOR& vResId)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
|
|
// Recupero le superfici di Riferimento
|
|
CISURFPVECTOR vRefSurf ; vRefSurf.reserve( vSurfId.size()) ;
|
|
bool bOk = true ;
|
|
for ( int i = 0 ; bOk && i < int( vSurfId.size()) ; ++ i) {
|
|
const ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( vSurfId[i])) ;
|
|
bOk = ( pSurf != nullptr && pSurf->IsValid()) ;
|
|
vRefSurf.emplace_back( pSurf) ;
|
|
}
|
|
|
|
// Recupero le superfici complessive, escludendo eventualmente quelle di riferimento se presenti
|
|
CISURFPVECTOR vOtherSurf ; vOtherSurf.reserve( vOtherSurfId.size()) ;
|
|
INTVECTOR vIds ;
|
|
for ( int i = 0 ; bOk && i < int( vOtherSurfId.size()) ; ++ i) {
|
|
if ( find( vSurfId.begin(), vSurfId.end(), vOtherSurfId[i]) == vSurfId.end()) {
|
|
const ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( vOtherSurfId[i])) ;
|
|
bOk = ( pSurf != nullptr && pSurf->IsValid()) ;
|
|
vOtherSurf.emplace_back( pSurf) ;
|
|
vIds.push_back( vOtherSurfId[i]) ;
|
|
}
|
|
}
|
|
|
|
// Recupero le facce adiancenti nella tolleranza richiesta
|
|
INTVECTOR vMyInds ;
|
|
bOk = bOk && GetTrimmingAdjSurfs( vRefSurf, vOtherSurf, dLinTol, dAngTol, dAngFaceTol, vMyInds) ;
|
|
if ( bOk) {
|
|
for ( int myInd : vMyInds)
|
|
vResId.push_back( vIds[myInd]) ;
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtTrimmingGetAdjSurfs(" + ToString( vSurfId) + "," +
|
|
ToString( vOtherSurfId) + "," +
|
|
ToString( dAngTol) + ")" +
|
|
" -- bOk=" + ToString( bOk) + ",vResId=" + ToString( vResId) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
bool
|
|
ExeTrimmingGetBorders( int nParentId, const SELVECTOR& vIds, double dSurfLinTol, double dSurfAngTol,
|
|
double dLinTol, double dAngTol, int& nFirstId, int& nCount)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
|
|
// Parametri da restituire
|
|
nFirstId = GDB_ID_NULL ;
|
|
nCount = 0 ;
|
|
|
|
// vIds : vettore di { nId = SurfId, nSubId = nSurfFace }
|
|
// Controllo che vIds non sia vuoto
|
|
bool bOk = ( ! vIds.empty()) ;
|
|
// Recupero il riferimento della prima superficie
|
|
Frame3d frSurf ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( vIds[0].nId, frSurf) ;
|
|
// Recupero il riferimento dei gruppi di destinazione
|
|
Frame3d frDest ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nParentId, frDest) ;
|
|
// Recupero gli Id univoci delle superfici selezionate
|
|
INTSET setUniqueId ;
|
|
for ( const SelData& nIds : vIds)
|
|
setUniqueId.insert( nIds.nId) ;
|
|
// Recupero le superfici e le porto tutte in locale alla prima
|
|
unordered_map<int, int> uMapPos ; uMapPos.reserve( setUniqueId.size()) ;
|
|
SURFLOCALVECTOR vSurfL ; vSurfL.reserve( setUniqueId.size()) ;
|
|
CISURFPVECTOR vpSurf ; vpSurf.reserve( setUniqueId.size()) ;
|
|
int nSurf = 0 ;
|
|
for ( auto nIter = setUniqueId.begin() ; bOk && nIter != setUniqueId.end() ; ++ nIter) {
|
|
vSurfL.emplace_back( pGeomDB, *nIter, frSurf) ;
|
|
bOk = ( vSurfL.back().Get() != nullptr) ;
|
|
vpSurf.emplace_back( vSurfL.back().Get()) ;
|
|
uMapPos[*nIter] = nSurf ;
|
|
++ nSurf ;
|
|
}
|
|
// Recupero il vettore di Selezione associato non più agli Id delle superficie ma alle loro posizioni nel vettore
|
|
SELVECTOR vFaces ; vFaces.reserve( vIds.size()) ;
|
|
for ( int i = 0 ; bOk && i < int( vIds.size()) ; ++ i)
|
|
vFaces.emplace_back( uMapPos[vIds[i].nId], vIds[i].nSub) ;
|
|
|
|
// Calcolo le curve di Edge grezze ( quindi i tratti lineari)
|
|
ICRVCOMPOPOVECTOR vRawEdges ;
|
|
bOk = bOk && GetTrimmingRawEdges( vpSurf, vFaces, dSurfLinTol, dSurfAngTol, vRawEdges) &&
|
|
( ! vRawEdges.empty()) ;
|
|
|
|
// Calcolo le curve di Edge approssimate mediante curve di Bezier
|
|
ICRVCOMPOPOVECTOR vBezierEdges ;
|
|
bOk = bOk && GetTrimmingBezierEdges( vRawEdges, dLinTol, dAngTol, vBezierEdges) ;
|
|
nCount = int( vBezierEdges.size()) ;
|
|
if ( bOk) {
|
|
// Scorro i gli Edges ottenuti
|
|
for ( int nCrv = 0 ; bOk && nCrv < nCount ; ++ nCrv) {
|
|
vBezierEdges[nCrv]->ToLoc( frDest) ;
|
|
// Inserisco la curva nel DB Geometrico
|
|
int nCurrId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( vBezierEdges[nCrv])) ;
|
|
bOk = ( nCurrId != GDB_ID_NULL) ;
|
|
if ( nCrv == 0)
|
|
nFirstId = nCurrId ;
|
|
}
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtTrimmingGetBorders(" + IdToString( nParentId) + "," +
|
|
ToString( dSurfLinTol) + "," +
|
|
ToString( dSurfAngTol) + "," +
|
|
ToString( dLinTol) + "," +
|
|
ToString( dAngTol) + ")" ;
|
|
sLua += " -- bOk=" + ToString( bOk) +
|
|
" -- FirstId=" + ToString( nFirstId) + " CurveCount=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
bool
|
|
ExeTrimmingGetBordersByNormals( int nParentId, const SELVECTOR& vIds, double dSurfLinTol,
|
|
double dSurfAngTol, double dLinTol, double dAngTol, double dThick,
|
|
int& nFirstId, int& nCount)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
|
|
// Parametri da restituire
|
|
nFirstId = GDB_ID_NULL ;
|
|
nCount = 0 ;
|
|
|
|
// vIds : vettore di { nId = SurfId, nSubId = nSurfFace }
|
|
// Controllo che vIds non sia vuoto
|
|
bool bOk = ( ! vIds.empty()) ;
|
|
// Recupero il riferimento della prima superficie
|
|
Frame3d frSurf ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( vIds[0].nId, frSurf) ;
|
|
// Recupero il riferimento dei gruppi di destinazione
|
|
Frame3d frDest ;
|
|
bOk = bOk && pGeomDB->GetGlobFrame( nParentId, frDest) ;
|
|
// Recupero gli Id univoci delle superfici selezionate
|
|
INTSET setUniqueId ;
|
|
for ( const SelData& nIds : vIds)
|
|
setUniqueId.insert( nIds.nId) ;
|
|
// Recupero le superfici e le porto tutte in locale alla prima
|
|
unordered_map<int, int> uMapPos ; uMapPos.reserve( setUniqueId.size()) ;
|
|
SURFLOCALVECTOR vSurfL ; vSurfL.reserve( setUniqueId.size()) ;
|
|
CISURFPVECTOR vpSurf ; vpSurf.reserve( setUniqueId.size()) ;
|
|
int nSurf = 0 ;
|
|
for ( auto nIter = setUniqueId.begin() ; bOk && nIter != setUniqueId.end() ; ++ nIter) {
|
|
vSurfL.emplace_back( pGeomDB, *nIter, frSurf) ;
|
|
bOk = ( vSurfL.back().Get() != nullptr) ;
|
|
vpSurf.emplace_back( vSurfL.back().Get()) ;
|
|
uMapPos[*nIter] = nSurf ;
|
|
++ nSurf ;
|
|
}
|
|
// Recupero il vettore di Selezione associato non più agli Id delle superficie ma alle loro posizioni nel vettore
|
|
SELVECTOR vFaces ; vFaces.reserve( vIds.size()) ;
|
|
for ( int i = 0 ; bOk && i < int( vIds.size()) ; ++ i)
|
|
vFaces.emplace_back( uMapPos[vIds[i].nId], vIds[i].nSub) ;
|
|
|
|
// Calcolo le curve di Edge approssimate mediante curve di Bezier
|
|
ICRVCOMPOPOVECTOR vBezierEdges ;
|
|
bOk = bOk && GetTrimmingFinalBorders( vpSurf, vFaces, dSurfLinTol, dSurfAngTol, dLinTol, dAngTol, dThick, vBezierEdges) ;
|
|
if ( bOk) {
|
|
nCount = int( vBezierEdges.size()) ;
|
|
// Scorro i gli Edges ottenuti
|
|
for ( int nCrv = 0 ; bOk && nCrv < nCount ; ++ nCrv) {
|
|
vBezierEdges[nCrv]->ToLoc( frDest) ;
|
|
// Inserisco la curva nel DB Geometrico
|
|
int nCurrId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( vBezierEdges[nCrv])) ;
|
|
bOk = ( nCurrId != GDB_ID_NULL) ;
|
|
if ( nCrv == 0)
|
|
nFirstId = nCurrId ;
|
|
}
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtTrimmingGetBordersByNormals(" + IdToString( nParentId) + "," +
|
|
ToString( dLinTol) + "," +
|
|
ToString( dAngTol) + ")" ;
|
|
sLua += " -- bOk=" + ToString( bOk) +
|
|
" -- FirstId=" + ToString( nFirstId) + " CurveCount=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
bool
|
|
ExeTrimmingGetFinalBorders( int nParentId, const INTVECTOR& vCrvBezierId, double dLinTol, double dAngTol,
|
|
const PNTVECTOR& vBrkPts, double dThick, double dThickTol,
|
|
int& nFirstId, int& nCount)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
|
|
// Parametri da restituire
|
|
nFirstId = GDB_ID_NULL ;
|
|
nCount = 0 ;
|
|
|
|
// Recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
bool bOk = ( pGeomDB->GetGlobFrame( nParentId, frDest)) ;
|
|
|
|
// Recupero le curve di Bordo approssimate come Bezier
|
|
ICRVCOMPOPOVECTOR vCompoBezierEdges ; vCompoBezierEdges.reserve( vCrvBezierId.size()) ;
|
|
for ( int nCrv = 0 ; bOk && nCrv < int( vCrvBezierId.size()) ; ++ nCrv) {
|
|
const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( vCrvBezierId[nCrv])) ;
|
|
bOk = ( pCrv != nullptr && pCrv->IsValid()) ;
|
|
if ( bOk) {
|
|
PtrOwner<ICurveComposite> pCompoRawEdges( ConvertCurveToComposite( pCrv->Clone())) ;
|
|
bOk = ( ! IsNull( pCompoRawEdges) && pCompoRawEdges->IsValid() &&
|
|
vCompoBezierEdges.emplace_back( Release( pCompoRawEdges))) ;
|
|
}
|
|
}
|
|
|
|
// Converto i punti in coppie di punti ( se dispari l'ultimo viene ignorato)
|
|
BIPNTVECTOR vBreakingPts ; vBreakingPts.reserve( int( int( vBrkPts.size()) / 2)) ;
|
|
for ( int nPt = 0 ; bOk && nPt < int( vBrkPts.size()) - 1 ; nPt += 2)
|
|
vBreakingPts.emplace_back( make_pair( vBrkPts[nPt], vBrkPts[nPt+1])) ;
|
|
if ( int( vBrkPts.size()) % 2 != 0)
|
|
LOG_INFO( GetCmdLogger(), "Warning in EgtExtractSurfFrChunkLoops : Odd number of breaking points") ;
|
|
|
|
// Calcolo le curve di Edge
|
|
bOk = bOk && GetTrimmingFinalBorders( vCompoBezierEdges, dLinTol, dAngTol, vBreakingPts, dThick, dThickTol) ;
|
|
nCount = int( vCompoBezierEdges.size()) ;
|
|
if ( bOk) {
|
|
// Scorro i gli Edges ottenuti
|
|
for ( int nCrv = 0 ; bOk && nCrv < nCount ; ++ nCrv) {
|
|
vCompoBezierEdges[nCrv]->ToLoc( frDest) ;
|
|
// Inserisco la curva nel DB Geometrico
|
|
int nCurrId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( vCompoBezierEdges[nCrv])) ;
|
|
bOk = ( nCurrId != GDB_ID_NULL) ;
|
|
if ( nCrv == 0)
|
|
nFirstId = nCurrId ;
|
|
}
|
|
ExeSetModified() ;
|
|
}
|
|
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtTrimmingGetFinalBorders(" + IdToString( nParentId) + "," +
|
|
ToString( vCrvBezierId) + "," +
|
|
ToString( dLinTol) + "," +
|
|
ToString( dAngTol) + "," ;
|
|
sLua += "{" ;
|
|
for ( int nP = 0 ; nP < int( vBrkPts.size()) ; ++ nP) {
|
|
sLua += "(" + ToString( vBrkPts[nP].x) + ", " + ToString( vBrkPts[nP].y) + ", " + ToString( vBrkPts[nP].z) + ")" +
|
|
( nP != int( vBrkPts.size()) - 1 ? "," : "") ;
|
|
}
|
|
sLua += "}" ;
|
|
sLua += ToString( dThick) + "," + ToString( dThickTol) + ")" ;
|
|
sLua += " -- bOk=" + ToString( bOk) +
|
|
" -- FirstId=" + ToString( nFirstId) + " CurveCount=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
int
|
|
ExeTrimmingGetRuledBezier( int nParentId, const INTVECTOR& vIds, int nEdge1Id, int nEdge2Id, double dLinTol,
|
|
const INTVECTOR& vnLineId)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
|
|
// Aggiusto la tolleranza lineare se necessario
|
|
double dMyLinTol = Clamp( dLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ;
|
|
|
|
// Recupero il riferimento dei gruppi di destinazione
|
|
Frame3d frDest ;
|
|
bool bOk = pGeomDB->GetGlobFrame( nParentId, frDest) ;
|
|
|
|
// Recupero la prima curva
|
|
const ICurve* pCrvEdge1 = GetCurve( pGeomDB->GetGeoObj( nEdge1Id)) ;
|
|
bOk = bOk && ( pCrvEdge1 != nullptr && pCrvEdge1->IsValid()) ;
|
|
|
|
// Recupero la seconda curva
|
|
const ICurve* pCrvEdge2 = GetCurve( pGeomDB->GetGeoObj( nEdge2Id)) ;
|
|
bOk = bOk && ( pCrvEdge2 != nullptr && pCrvEdge2->IsValid()) ;
|
|
|
|
// Se ci sono delle superfici di riferimento
|
|
CISURFPVECTOR vpSurf ; vpSurf.reserve( vIds.size()) ;
|
|
if ( ! vIds.empty()) {
|
|
SURFLOCALVECTOR vSurfL ; vSurfL.reserve( vIds.size()) ;
|
|
// Recupero il riferimento della prima superficie
|
|
Frame3d frSurf ;
|
|
bOk = bOk && ( pGeomDB->GetGlobFrame( vIds[0], frSurf)) ;
|
|
// Porto le altre nel riferimento della prima
|
|
for ( int nSurf = 0 ; bOk && nSurf < int( vIds.size()) ; ++ nSurf) {
|
|
vSurfL.emplace_back( pGeomDB, vIds[nSurf], frSurf) ;
|
|
if ( vSurfL.back().Get() == nullptr) {
|
|
bOk = false ;
|
|
break ;
|
|
}
|
|
vpSurf.emplace_back( vSurfL.back().Get()) ;
|
|
}
|
|
}
|
|
|
|
// Recupero i punti di sincronizzazione ( se presenti)
|
|
BIPNTVECTOR vSyncPoints ; vSyncPoints.reserve( pGeomDB->GetGroupObjs( vnLineId.size())) ;
|
|
for ( int i = 0 ; bOk && i < ssize( vnLineId) ; ++ i) {
|
|
// Recupero la Curva
|
|
const ICurve* pLine = GetCurve( pGeomDB->GetGeoObj( vnLineId[i])) ;
|
|
bOk = bOk && ( pLine != nullptr && pLine->IsValid()) ;
|
|
if ( bOk) {
|
|
// Recupero gli Estremi
|
|
Point3d ptStart ; pLine->GetStartPoint( ptStart) ;
|
|
Point3d ptEnd ; pLine->GetEndPoint( ptEnd) ;
|
|
// Mi assicuro che gli estremi siano sulle curve di Bordo e orientati correttamente ( nel caso inverto)
|
|
double dSqDistS1 = INFINITO ;
|
|
if ( ! DistPointCurve( ptStart, *pCrvEdge1).GetSqDist( dSqDistS1))
|
|
continue ;
|
|
if ( dSqDistS1 < dLinTol * dLinTol) {
|
|
double dSqDistE2 = INFINITO ;
|
|
if ( ! DistPointCurve( ptEnd, *pCrvEdge2).GetSqDist( dSqDistE2) ||
|
|
dSqDistE2 > dLinTol * dLinTol)
|
|
continue ;
|
|
}
|
|
else {
|
|
double dSqDistS2 = INFINITO ;
|
|
if ( ! DistPointCurve( ptStart, *pCrvEdge2).GetSqDist( dSqDistS2) ||
|
|
dSqDistS2 > dLinTol * dLinTol)
|
|
continue ;
|
|
double dSqDistE1 = INFINITO ;
|
|
if ( ! DistPointCurve( ptEnd, *pCrvEdge1).GetSqDist( dSqDistE1) ||
|
|
dSqDistE1 > dLinTol * dLinTol)
|
|
continue ;
|
|
swap( ptStart, ptEnd) ;
|
|
}
|
|
vSyncPoints.emplace_back( make_pair( ptStart, ptEnd)) ;
|
|
}
|
|
}
|
|
|
|
// Recupero la superficie Bezier rigata
|
|
PtrOwner<ISurfBezier> pSurfBzRuled ;
|
|
if ( bOk) {
|
|
pSurfBzRuled.Set( GetTrimmingRuledBezier( vpSurf, pCrvEdge1, pCrvEdge2, dMyLinTol, vSyncPoints)) ;
|
|
bOk = bOk && ( ! IsNull( pSurfBzRuled) && pSurfBzRuled->IsValid()) ;
|
|
}
|
|
|
|
// Inserisco la curva nel DB Geometrico
|
|
int nSurfBzId = GDB_ID_NULL ;
|
|
if ( bOk) {
|
|
pSurfBzRuled->ToLoc( frDest) ;
|
|
nSurfBzId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSurfBzRuled)) ;
|
|
bOk = bOk && ( nSurfBzId != GDB_ID_NULL) ;
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtTrimmingGetRuledBezier(" + ToString( nParentId) + "," +
|
|
ToString( vIds) + "," +
|
|
ToString( nEdge1Id) + "," +
|
|
ToString( nEdge2Id) + "," +
|
|
ToString( dLinTol) + ")" +
|
|
" -- bOk=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
// Restituisco il risultato
|
|
return nSurfBzId ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
bool
|
|
ExeTrimmingInterpolateSyncLines( int nParentId, int nSync1Id, int nSync2Id, int nBorder1Id,
|
|
int nBorder2Id, double dEdgeLinTol, double dEdgeAngTol,
|
|
int& nFirstId, int& nCount)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
|
|
// Reset parametri di ritorno
|
|
nFirstId = GDB_ID_NULL ;
|
|
nCount = 0 ;
|
|
|
|
// Aggiusto la tolleranza lineare e angolare se necessario
|
|
double dMyEdgeLinTol = Clamp( dEdgeLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ;
|
|
double dMyEdgeAngTol = Clamp( dEdgeAngTol, EPS_ANG_SMALL, 60.) ;
|
|
|
|
// recupero le due curve di sincronizzazione
|
|
const ICurve* pSync1 = GetCurve( pGeomDB->GetGeoObj( nSync1Id)) ;
|
|
const ICurve* pSync2 = GetCurve( pGeomDB->GetGeoObj( nSync2Id)) ;
|
|
bool bOk = ( pSync1 != nullptr && pSync1->IsValid() &&
|
|
pSync2 != nullptr && pSync2->IsValid()) ;
|
|
|
|
// Recupero le due curve di bordo
|
|
const ICurve* pCrvEdge1 = GetCurve( pGeomDB->GetGeoObj( nBorder1Id)) ;
|
|
const ICurve* pCrvEdge2 = GetCurve( pGeomDB->GetGeoObj( nBorder2Id)) ;
|
|
bOk = bOk && ( pCrvEdge1 != nullptr && pCrvEdge1->IsValid()) ;
|
|
bOk = bOk && ( pCrvEdge2 != nullptr && pCrvEdge2->IsValid()) ;
|
|
|
|
// Calcolo le Curve di sincornizzazione Interpolate
|
|
BIPNTVECTOR vSyncPoints ;
|
|
bOk = bOk && GetTrimmingSyncInterpolation( pCrvEdge1, pCrvEdge2, pSync1, pSync2, dMyEdgeLinTol,
|
|
dMyEdgeAngTol, vSyncPoints) ;
|
|
if ( bOk && ! vSyncPoints.empty()) {
|
|
// Inserisco le curve di sincronizzazione nel DB
|
|
// [orientate da pCrvEdge1 a pCrvEdge2]
|
|
for ( int i = 0 ; bOk && i < ssize( vSyncPoints) ; ++ i) {
|
|
PtrOwner<ICurveLine> pSyncLine( CreateCurveLine()) ;
|
|
bOk = ( ! IsNull( pSyncLine) && pSyncLine->Set( vSyncPoints[i].first, vSyncPoints[i].second)) ;
|
|
if ( bOk) {
|
|
if ( pCrvEdge1->IsPointOn( vSyncPoints[i].second, dMyEdgeLinTol))
|
|
pSyncLine->Invert() ;
|
|
int nSyncId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSyncLine)) ;
|
|
bOk = ( nSyncId != CMD_ID_NULL) ;
|
|
if ( i == 0)
|
|
nFirstId = nSyncId ;
|
|
}
|
|
}
|
|
nCount = ssize( vSyncPoints) ;
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtTrimmingInterpolateSyncLines(" + ToString( nParentId) + "," +
|
|
ToString( nSync1Id) + "," +
|
|
ToString( nSync2Id) + "," +
|
|
ToString( nBorder1Id) + "," +
|
|
ToString( nBorder2Id) + "," +
|
|
ToString( dEdgeLinTol) + "," +
|
|
ToString( dEdgeAngTol) + ")" +
|
|
" -- bOk=" + ToString( bOk) +
|
|
" -- nFirstId=" + ToString( nFirstId) + " nCount=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
bool
|
|
ExeTrimmingGetSurfBzSyncPoints( int nParentId, int nEdge1Id, int nEdge2Id, double dLinTol,
|
|
double dAngTol, int nLineNbr, bool bShowOnCorners,
|
|
int& nFirstId, int& nCount)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
|
|
// Imposto i parametri di ritorno
|
|
nFirstId = GDB_ID_NULL ;
|
|
nCount = 0 ;
|
|
|
|
// Se non devo visualizzare alcuna linea, non faccio nulla
|
|
if ( nLineNbr <= 0 && ! bShowOnCorners)
|
|
return true ;
|
|
|
|
// Se necessario aggiusto le tolleranze
|
|
double dMyLinTol = Clamp( dLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ;
|
|
double dMyAngTol = Clamp( dAngTol, EPS_ANG_SMALL, ANG_RIGHT) ;
|
|
|
|
// Recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
bool bOk = ( pGeomDB->GetGlobFrame( nParentId, frDest)) ;
|
|
|
|
// Recupero le due Curve di bordo
|
|
const ICurve* pCrvEdge1 = GetCurve( pGeomDB->GetGeoObj( nEdge1Id)) ;
|
|
const ICurve* pCrvEdge2 = GetCurve( pGeomDB->GetGeoObj( nEdge2Id)) ;
|
|
bOk = bOk && ( pCrvEdge1 != nullptr && pCrvEdge1->IsValid() &&
|
|
pCrvEdge2 != nullptr && pCrvEdge2->IsValid()) ;
|
|
|
|
// Verifico che le curve siano entrambe Aperte o entrambe Chiuse
|
|
bOk = bOk && ( pCrvEdge1->IsClosed() == pCrvEdge2->IsClosed()) ;
|
|
|
|
// Recupero i punti di sincronizzazione
|
|
BIPNTVECTOR vSyncPoints ;
|
|
bOk = bOk && GetTrimmingSurfBzSyncPoints( pCrvEdge1, pCrvEdge2, dMyLinTol, vSyncPoints) &&
|
|
( ! vSyncPoints.empty()) ;
|
|
int nToTSyncLines = ssize( vSyncPoints) ;
|
|
|
|
// Ogni punto di sincronizzazione deve avere gli estremi sulle curve di Bordo
|
|
for ( int i = 0 ; bOk && i < ssize( vSyncPoints) ; ++ i) {
|
|
double dSqDistStart = INFINITO, dSqDistEnd = INFINITO ;
|
|
bOk = ( DistPointCurve( vSyncPoints[i].first, *pCrvEdge1).GetSqDist( dSqDistStart) &&
|
|
dSqDistStart < dMyLinTol * dMyLinTol &&
|
|
DistPointCurve( vSyncPoints[i].second, *pCrvEdge2).GetSqDist( dSqDistEnd) &&
|
|
dSqDistEnd < dMyLinTol * dMyLinTol) ;
|
|
}
|
|
|
|
if ( bOk) {
|
|
INTSET setInds ;
|
|
// Se devo visualizzare più linee di quante ne ho ricavate, allora le devo visualizzare tutte
|
|
if ( nLineNbr >= nToTSyncLines) {
|
|
for ( int i = 0 ; i < nToTSyncLines ; ++ i)
|
|
setInds.insert( i) ;
|
|
}
|
|
// Altrimenti
|
|
else {
|
|
// Se voglio visualizzare gli Spigoli
|
|
if ( bShowOnCorners) {
|
|
for ( int nL = 0 ; bOk && nL < nToTSyncLines ; ++ nL) {
|
|
// Controllo se punto su spigolo della curva
|
|
double dU = 0. ;
|
|
Vector3d vtTanPrev, vtTanAft ;
|
|
Point3d ptUseless ;
|
|
bOk = ( pCrvEdge1->GetParamAtPoint( vSyncPoints[nL].first, dU, dMyLinTol) &&
|
|
pCrvEdge1->GetPointD1D2( dU, ICurve::FROM_MINUS, ptUseless, &vtTanPrev) &&
|
|
pCrvEdge1->GetPointD1D2( dU, ICurve::FROM_PLUS, ptUseless, &vtTanAft)) ;
|
|
if ( ! bOk)
|
|
break ;
|
|
vtTanPrev.Normalize() ;
|
|
vtTanAft.Normalize() ;
|
|
if ( vtTanPrev * vtTanAft < cos( ( dMyAngTol + EPS_ANG_SMALL) * DEGTORAD)) {
|
|
setInds.insert( nL) ;
|
|
continue ;
|
|
}
|
|
bOk = ( pCrvEdge2->GetParamAtPoint( vSyncPoints[nL].second, dU, dMyLinTol) &&
|
|
pCrvEdge2->GetPointD1D2( dU, ICurve::FROM_MINUS, ptUseless, &vtTanPrev) &&
|
|
pCrvEdge2->GetPointD1D2( dU, ICurve::FROM_PLUS, ptUseless, &vtTanAft)) ;
|
|
if ( ! bOk)
|
|
break ;
|
|
vtTanPrev.Normalize() ;
|
|
vtTanAft.Normalize() ;
|
|
if ( vtTanPrev * vtTanAft < cos( ( dMyAngTol + EPS_ANG_SMALL) * DEGTORAD)) {
|
|
setInds.insert( nL) ;
|
|
continue ;
|
|
}
|
|
}
|
|
}
|
|
// Se devo mostrare alcune Linee
|
|
if ( bOk && nLineNbr > 0) {
|
|
bool bBothOpen = ( ! pCrvEdge1->IsClosed() && ! pCrvEdge2->IsClosed()) ;
|
|
bool bBothClosed = ( ! bBothOpen) ;
|
|
int nLastIdx = nToTSyncLines - 1 ;
|
|
if ( bBothClosed) {
|
|
int nLine = nLineNbr ;
|
|
if ( nLine == 1)
|
|
setInds.insert( 0) ;
|
|
else {
|
|
int nMaxIndex = nToTSyncLines - 2 ;
|
|
for ( int i = 0 ; i < nLine ; ++ i) {
|
|
double dT = double( i) / double( nLine) ;
|
|
int nIdx = int( 0.5 + dT * nMaxIndex) ;
|
|
setInds.insert( nIdx) ;
|
|
}
|
|
setInds.erase( nLastIdx) ;
|
|
}
|
|
}
|
|
else {
|
|
int nInternal = nLineNbr ;
|
|
setInds.insert( 0) ;
|
|
setInds.insert( nLastIdx) ;
|
|
int nMaxIndex = nLastIdx ;
|
|
for ( int i = 0; i < nInternal ; ++ i) {
|
|
double dT = double( i + 1) / double( nInternal + 1) ;
|
|
int nIdx = int( 0.5 + dT * nMaxIndex) ;
|
|
setInds.insert( nIdx) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Visualizzo i segmenti lineari di sincronizzazione per ogni indice ricavato
|
|
bool bFirst = true ;
|
|
for ( auto Iter = setInds.begin() ; bOk && Iter != setInds.end() ; ++ Iter) {
|
|
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
|
bOk = ( ! IsNull( pLine) && pLine->Set( vSyncPoints[*Iter].first, vSyncPoints[*Iter].second)) ;
|
|
if ( bOk) {
|
|
int nLineId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pLine)) ;
|
|
bOk = ( nLineId != GDB_ID_NULL) ;
|
|
if ( bFirst) {
|
|
nFirstId = nLineId ;
|
|
bFirst = false ;
|
|
}
|
|
++ nCount ;
|
|
}
|
|
}
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtTrimmingGetSurfBzSyncPoints(" + ToString( nParentId) + "," +
|
|
ToString( nEdge1Id) + "," +
|
|
ToString( nEdge2Id) + "," +
|
|
ToString( dLinTol) + "," +
|
|
ToString( nFirstId) + "," +
|
|
ToString( nCount) + ")" +
|
|
" -- bOk=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
bool
|
|
ExeTrimmingGetToolOrientationLines( int nParentId, int nMainEdgeId, int nOtherEdgeId, bool bMainIsFirstBorder, int nSyncLayerId,
|
|
int nLineSId, int nLineEId, bool bShorterSide,
|
|
double dThetaStart, double dPhiStart, double dThetaEnd, double dPhiEnd, double dInterpLenS,
|
|
double dInterpLenE, double dLinTol,
|
|
int& nInterpStartId, int& nStartId, int& nEndId, int& nInterpEndId)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
|
|
// Imposto i parametri di ritorno
|
|
nInterpStartId = GDB_ID_NULL, nStartId = GDB_ID_NULL, nEndId = GDB_ID_NULL, nInterpEndId = GDB_ID_NULL ;
|
|
|
|
// Se necessario aggiusto le tolleranze
|
|
double dMyLinTol = Clamp( dLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ;
|
|
const double TOL = dMyLinTol ;
|
|
// Definisco costanti per interpolazione
|
|
const double INTERPOLATION_DIST = 2 ;
|
|
const double ISO_PAR_SAMPLE = 20.0 ;
|
|
|
|
// Recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
bool bOk = ( pGeomDB->GetGlobFrame( nParentId, frDest)) ;
|
|
|
|
// Recupero le due Curve di bordo
|
|
const ICurve* pCrvMainEdge = GetCurve( pGeomDB->GetGeoObj( nMainEdgeId)) ;
|
|
const ICurve* pCrvOtherEdge = GetCurve( pGeomDB->GetGeoObj( nOtherEdgeId)) ;
|
|
bOk = bOk && ( pCrvMainEdge != nullptr && pCrvMainEdge->IsValid() && pCrvOtherEdge != nullptr && pCrvOtherEdge->IsValid()) ;
|
|
|
|
// Verifico che le curve siano entrambe Aperte o entrambe Chiuse e memorizzo il risultato
|
|
bOk = bOk && ( pCrvMainEdge->IsClosed() == pCrvOtherEdge->IsClosed()) ;
|
|
bool bBorderClosed = ( pCrvMainEdge->IsClosed()) ;
|
|
|
|
// Recupero le Linee di Sincronizzazione iniziali e finali e verifico che giacciano sulle Curve di Bordo
|
|
PtrOwner<ICurve> pCrvSyncS( GetCurve( pGeomDB->GetGeoObj( nLineSId))->Clone()) ;
|
|
PtrOwner<ICurve> pCrvSyncE( GetCurve( pGeomDB->GetGeoObj( nLineEId))->Clone()) ;
|
|
bOk = bOk && ( pCrvSyncS != nullptr && pCrvSyncS->IsValid() && pCrvSyncE != nullptr && pCrvSyncE->IsValid()) ;
|
|
BIPOINT Line1, Line2 ;
|
|
bOk = bOk && ( pCrvSyncS->GetStartPoint( Line1.first)) && ( pCrvSyncS->GetEndPoint( Line1.second)) ;
|
|
bOk = bOk && ( pCrvSyncE->GetStartPoint( Line2.first)) && ( pCrvSyncE->GetEndPoint( Line2.second)) ;
|
|
// --- se necessario oriento le linee di Sync in modo che inizino entrambe dal Bordo Main
|
|
if ( bOk) {
|
|
if ( pCrvMainEdge->IsPointOn( Line1.first, TOL))
|
|
bOk = ( pCrvOtherEdge->IsPointOn( Line1.second, TOL)) ;
|
|
else if ( pCrvOtherEdge->IsPointOn( Line1.first, TOL)) {
|
|
bOk = ( pCrvMainEdge->IsPointOn( Line1.second, TOL)) ;
|
|
if ( bOk) {
|
|
swap( Line1.first, Line1.second) ;
|
|
pCrvSyncS->Invert() ;
|
|
}
|
|
}
|
|
else
|
|
bOk = false ;
|
|
}
|
|
if ( bOk) {
|
|
if ( pCrvMainEdge->IsPointOn( Line2.first, TOL))
|
|
bOk = ( pCrvOtherEdge->IsPointOn( Line2.second, TOL)) ;
|
|
else if ( pCrvOtherEdge->IsPointOn( Line2.first, TOL)) {
|
|
bOk = ( pCrvMainEdge->IsPointOn( Line2.second, TOL)) ;
|
|
if ( bOk) {
|
|
swap( Line2.first, Line2.second) ;
|
|
pCrvSyncE->Invert() ;
|
|
}
|
|
}
|
|
else bOk = false ;
|
|
}
|
|
// Il percorso selezionato è il minore tra le due possibilità di percorrenza
|
|
if ( bOk && bBorderClosed) {
|
|
double dParS = 0. ;
|
|
PtrOwner<ICurveComposite> pCompoMainCL( ConvertCurveToComposite( pCrvMainEdge->Clone())) ;
|
|
bOk = ( ! IsNull( pCompoMainCL) && pCompoMainCL->IsValid() &&
|
|
pCompoMainCL->GetParamAtPoint( Line1.first, dParS, TOL)) ;
|
|
if ( bOk) {
|
|
pCompoMainCL->ChangeStartPoint( dParS) ;
|
|
double dLenE = 0., dLenMain = 0. ;
|
|
bOk = ( pCompoMainCL->GetLengthAtPoint( Line2.first, dLenE, TOL) &&
|
|
pCompoMainCL->GetLength( dLenMain)) ;
|
|
if ( dLenE > dLenMain / 2. + EPS_SMALL && bShorterSide) {
|
|
swap( Line1, Line2) ;
|
|
swap( pCrvSyncS, pCrvSyncE) ;
|
|
swap( dThetaStart, dThetaEnd) ;
|
|
swap( dPhiStart, dPhiEnd) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Calcolo la lunghezza delle due curve di Bordo
|
|
double dLenMain = 0., dLenOther = 0. ;
|
|
bOk = bOk && ( pCrvMainEdge->GetLength( dLenMain) && pCrvOtherEdge->GetLength( dLenOther) &&
|
|
dLenMain > 2. * TOL + dInterpLenS + dInterpLenE + EPS_SMALL &&
|
|
dLenOther > 2. * TOL + dInterpLenS + dInterpLenE + EPS_SMALL) ;
|
|
|
|
// Recupero i punti di sincronizzazione (se presenti)
|
|
BIPNTVECTOR vSyncPoints ; vSyncPoints.reserve( pGeomDB->GetGroupObjs( nSyncLayerId)) ;
|
|
int nLineId = pGeomDB->GetFirstInGroup( nSyncLayerId) ;
|
|
while ( bOk && nLineId != GDB_ID_NULL) {
|
|
// Recupero la Curva
|
|
const ICurve* pLine = GetCurve( pGeomDB->GetGeoObj( nLineId)) ;
|
|
bOk = bOk && ( pLine != nullptr && pLine->IsValid()) ;
|
|
if ( bOk) {
|
|
// Recupero gli Estremi
|
|
Point3d ptStart ; pLine->GetStartPoint( ptStart) ;
|
|
Point3d ptEnd ; pLine->GetEndPoint( ptEnd) ;
|
|
// Mi assicuro che gli estremi siano sulle curve di Bordo ( in un verso o nell'altro, mantengo il verso)
|
|
double dDistS1 = INFINITO ;
|
|
if ( ! DistPointCurve( ptStart, *pCrvMainEdge).GetDist( dDistS1)) {
|
|
nLineId = pGeomDB->GetNext( nLineId) ;
|
|
continue ;
|
|
}
|
|
if ( dDistS1 < dLinTol) {
|
|
double dDistE2 = INFINITO ;
|
|
if ( ! DistPointCurve( ptEnd, *pCrvOtherEdge).GetDist( dDistE2) || dDistE2 > dLinTol) {
|
|
nLineId = pGeomDB->GetNext( nLineId) ;
|
|
continue ;
|
|
}
|
|
}
|
|
else {
|
|
double dDistS2 = INFINITO ;
|
|
if ( ! DistPointCurve( ptStart, *pCrvOtherEdge).GetDist( dDistS2) || dDistS2 > dLinTol) {
|
|
nLineId = pGeomDB->GetNext( nLineId) ;
|
|
continue ;
|
|
}
|
|
double dDistE1 = INFINITO ;
|
|
if ( ! DistPointCurve( ptEnd, *pCrvMainEdge).GetDist( dDistE1) || dDistE1 > dLinTol) {
|
|
nLineId = pGeomDB->GetNext( nLineId) ;
|
|
continue ;
|
|
}
|
|
}
|
|
vSyncPoints.emplace_back( make_pair( ptStart, ptEnd)) ;
|
|
}
|
|
nLineId = pGeomDB->GetNext( nLineId) ;
|
|
}
|
|
|
|
// Recupero la superficie Bezier rigata
|
|
PtrOwner<ISurfBezier> pSurfBzRuled ;
|
|
if ( bOk) {
|
|
if ( bMainIsFirstBorder) {
|
|
// Se non ho linee di sincronizzazione
|
|
if ( vSyncPoints.empty())
|
|
pSurfBzRuled.Set( GetSurfBezierRuledSmooth( pCrvMainEdge, pCrvOtherEdge, vSyncPoints, ISO_PAR_SAMPLE)) ;
|
|
// Se ho linee di sincronizzazione
|
|
else
|
|
pSurfBzRuled.Set( GetSurfBezierRuledGuided( pCrvMainEdge, pCrvOtherEdge, vSyncPoints, dMyLinTol)) ;
|
|
}
|
|
else {
|
|
// Se non ho linee di sincronizzazione
|
|
if ( vSyncPoints.empty())
|
|
pSurfBzRuled.Set( GetSurfBezierRuledSmooth( pCrvOtherEdge, pCrvMainEdge, vSyncPoints, ISO_PAR_SAMPLE)) ;
|
|
// Se ho linee di sincronizzazione
|
|
else
|
|
pSurfBzRuled.Set( GetSurfBezierRuledGuided( pCrvOtherEdge, pCrvMainEdge, vSyncPoints, dMyLinTol)) ;
|
|
}
|
|
bOk = bOk && ( ! IsNull( pSurfBzRuled) && pSurfBzRuled->IsValid()) ;
|
|
}
|
|
|
|
// --- Calcolo delle Linee di Orientamento ---
|
|
if ( bOk) {
|
|
|
|
// Rotazione delle curve di Bordo rispetto al Bordo Main
|
|
double dLenS ; pCrvSyncS->GetLength( dLenS) ;
|
|
Line1.second = Line1.first + FromSpherical( dLenS, dThetaStart, dPhiStart) ;
|
|
double dLenE ; pCrvSyncE->GetLength( dLenE) ;
|
|
Line2.second = Line2.first + FromSpherical( dLenE, dThetaEnd, dPhiEnd) ;
|
|
|
|
// --- Eventuale Interpolazione Lineare di Raccordo all'Inizio ---
|
|
if ( dInterpLenS > TOL) {
|
|
double dExtension = dInterpLenS ;
|
|
double dLen = -1. ; pCrvMainEdge->GetLengthAtPoint( Line1.first, dLen, TOL) ;
|
|
if ( bBorderClosed) {
|
|
dLen -= dInterpLenS ;
|
|
if ( dLen < EPS_SMALL)
|
|
dLen = dLenMain + dLen ;
|
|
}
|
|
else {
|
|
if ( dLen < dInterpLenS - EPS_SMALL) {
|
|
dExtension = dLen ;
|
|
dLen = 0 ;
|
|
}
|
|
}
|
|
double dU = - 1;
|
|
bOk = pCrvMainEdge->GetParamAtLength( dLen, dU) ;
|
|
if ( bOk) {
|
|
// Definisco la linea si sincronizzazione
|
|
Point3d ptInterpS ; double dParU, dParV ;
|
|
PtrOwner<ICurveComposite> pCompoIso( nullptr) ;
|
|
BIPOINT LineInterpS ;
|
|
bOk = ( pCrvMainEdge->GetPointD1D2( dU, ICurve::FROM_MINUS, ptInterpS) &&
|
|
DistPointSurfBz( ptInterpS, *pSurfBzRuled).GetParamsAtMinDistPoint( dParU, dParV) &&
|
|
pCompoIso.Set( pSurfBzRuled->GetCurveOnV( dParU)) &&
|
|
pCompoIso->IsValid() &&
|
|
pCompoIso->GetStartPoint( LineInterpS.first) &&
|
|
pCompoIso->GetEndPoint( LineInterpS.second)) ;
|
|
if ( ! bMainIsFirstBorder)
|
|
swap( LineInterpS.first, LineInterpS.second) ;
|
|
if ( bOk) {
|
|
bool bFirst = true ;
|
|
// Interpolo
|
|
double dLenLineInterpS = Dist( LineInterpS.first, LineInterpS.second) ;
|
|
double dLenLine1 = Dist( Line1.first, Line1.second) ;
|
|
int nStep = max( 1, int( ceil( dExtension / INTERPOLATION_DIST))) ;
|
|
Vector3d vtInterpStart = ( LineInterpS.second - LineInterpS.first) ; vtInterpStart.Normalize() ;
|
|
Vector3d vtInterpEnd = ( Line1.second - Line1.first) ; vtInterpEnd.Normalize() ;
|
|
Vector3d vtDiff = vtInterpEnd - vtInterpStart ;
|
|
for ( int i = 0 ; bOk && i < ( nStep - 1) ; ++ i) { // ( nStep - 1) per evitare sovrapposizione con la Copia del vettore
|
|
double dI = double( i) ;
|
|
Vector3d vtInterp = vtInterpStart + ( dI / ( nStep - 1)) * vtDiff ;
|
|
double dUInterpMain = 0. ; Point3d ptInterpOnMain ;
|
|
double dCurrLen = dLen + ( dI * dExtension / ( nStep - 1)) ;
|
|
if ( dCurrLen > dLenMain)
|
|
dCurrLen -= dLenMain ;
|
|
bOk = ( pCrvMainEdge->GetParamAtLength( dCurrLen, dUInterpMain) &&
|
|
pCrvMainEdge->GetPointD1D2( dUInterpMain, ICurve::FROM_MINUS, ptInterpOnMain)) ;
|
|
if ( bOk) {
|
|
double dMagnitude = dLenLineInterpS + ( dI / ( nStep - 1)) * ( dLenLine1 - dLenLineInterpS) ;
|
|
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
|
bOk = ( ! IsNull( pLine) && pLine->Set( ptInterpOnMain, ptInterpOnMain + vtInterp * dMagnitude)) ;
|
|
if ( bOk) {
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pLine)) ;
|
|
bOk = ( nNewId != GDB_ID_NULL) ;
|
|
if ( bOk) {
|
|
if ( bFirst) {
|
|
nInterpStartId = nNewId ;
|
|
bFirst = false ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// --- Interpolazione tra le due Linee di Sincronizzazione ---
|
|
if ( bOk) {
|
|
double dLenS = -1., dLenE = -1 ;
|
|
bOk = ( pCrvMainEdge->GetLengthAtPoint( Line1.first, dLenS, TOL) &&
|
|
pCrvMainEdge->GetLengthAtPoint( Line2.first, dLenE, TOL)) ;
|
|
if ( bOk) {
|
|
double dToTDist = 0. ;
|
|
if ( dLenS < dLenE)
|
|
dToTDist = dLenE - dLenS ;
|
|
else
|
|
dToTDist = ( dLenMain - dLenS) + dLenE ;
|
|
if ( dToTDist > TOL) {
|
|
bool bFirst = true ;
|
|
// Interpolo
|
|
double dLenLine1 = Dist( Line1.first, Line1.second) ;
|
|
double dLenLine2 = Dist( Line2.first, Line2.second) ;
|
|
int nStep = max( 1, int( ceil( dToTDist / INTERPOLATION_DIST))) ;
|
|
Vector3d vtLineS = ( Line1.second - Line1.first) ; vtLineS.Normalize() ;
|
|
Vector3d vtLineE = ( Line2.second - Line2.first) ; vtLineE.Normalize() ;
|
|
Vector3d vtDiff = ( vtLineE - vtLineS) ;
|
|
for ( int i = 0 ; bOk && i <= nStep ; ++ i) {
|
|
double dI = double( i) ;
|
|
Vector3d vtInterp = vtLineS + ( dI / nStep) * vtDiff ;
|
|
double dUInterpMain = 0. ; Point3d ptInterpOnMain ;
|
|
double dCurrLen = dLenS + ( dI * dToTDist / nStep) ;
|
|
if ( dCurrLen > dLenMain)
|
|
dCurrLen -= dLenMain ;
|
|
bOk = ( pCrvMainEdge->GetParamAtLength( dCurrLen, dUInterpMain) &&
|
|
pCrvMainEdge->GetPointD1D2( dUInterpMain, ICurve::FROM_MINUS, ptInterpOnMain)) ;
|
|
if ( bOk) {
|
|
double dMagnitude = dLenLine1 + ( dI / nStep) * ( dLenLine2 - dLenLine1) ;
|
|
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
|
bOk = ( ! IsNull( pLine) && pLine->Set( ptInterpOnMain, ptInterpOnMain + vtInterp * dMagnitude)) ;
|
|
if ( bOk) {
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pLine)) ;
|
|
bOk = ( nNewId != GDB_ID_NULL) ;
|
|
if ( bOk) {
|
|
if ( bFirst) {
|
|
nStartId = nNewId ;
|
|
bFirst = false ;
|
|
}
|
|
nEndId = nNewId ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// --- Eventuale Interpolazione Lineare di Raccordo alla Fine ---
|
|
if ( bOk && dInterpLenE > TOL) {
|
|
double dExtension = dInterpLenE ;
|
|
double dLen = -1. ; pCrvMainEdge->GetLengthAtPoint( Line2.first, dLen, TOL) ;
|
|
if ( bBorderClosed) {
|
|
dLen += dInterpLenE ;
|
|
if ( dLen > dLenMain - EPS_SMALL)
|
|
dLen -= dLenMain ;
|
|
}
|
|
else {
|
|
if ( dLen > dLenMain - dInterpLenE - EPS_SMALL) {
|
|
dExtension = dLenMain - dLen ;
|
|
dLen = dLenMain ;
|
|
}
|
|
}
|
|
double dU = - 1 ;
|
|
bOk = pCrvMainEdge->GetParamAtLength( dLen, dU) ;
|
|
if ( bOk) {
|
|
// Definisco la linea si sincronizzazione
|
|
Point3d ptInterpE ; double dParU, dParV ;
|
|
PtrOwner<ICurveComposite> pCompoIso( nullptr) ;
|
|
BIPOINT LineInterpE ;
|
|
bOk = ( pCrvMainEdge->GetPointD1D2( dU, ICurve::FROM_MINUS, ptInterpE) &&
|
|
DistPointSurfBz( ptInterpE, *pSurfBzRuled).GetParamsAtMinDistPoint( dParU, dParV) &&
|
|
pCompoIso.Set( pSurfBzRuled->GetCurveOnV( dParU)) &&
|
|
pCompoIso->IsValid() &&
|
|
pCompoIso->GetStartPoint( LineInterpE.first) &&
|
|
pCompoIso->GetEndPoint( LineInterpE.second)) ;
|
|
if ( ! bMainIsFirstBorder)
|
|
swap( LineInterpE.first, LineInterpE.second) ;
|
|
if ( bOk) {
|
|
// Interpolo
|
|
double dLenLineInterpE = Dist( LineInterpE.first, LineInterpE.second) ;
|
|
double dLenLine2 = Dist( Line2.first, Line2.second) ;
|
|
int nStep = max( 1, int( ceil( dExtension / INTERPOLATION_DIST))) ;
|
|
Vector3d vtInterpStart = ( Line2.second - Line2.first) ; vtInterpStart.Normalize() ;
|
|
Vector3d vtInterpEnd = ( LineInterpE.second - LineInterpE.first) ; vtInterpEnd.Normalize() ;
|
|
Vector3d vtDiff = vtInterpEnd - vtInterpStart ;
|
|
for ( int i = 1 ; bOk && i < nStep ; ++ i) { // i = 1 per evitare la sopvrapposizione con la Copia del vettore
|
|
double dI = double( i) ;
|
|
Vector3d vtInterp = vtInterpStart + ( dI / ( nStep - 1)) * vtDiff ;
|
|
double dUInterpMain = 0. ; Point3d ptInterpOnMain ;
|
|
double dCurrLen = ( dLen - dExtension) + ( dI * dExtension / ( nStep - 1)) ;
|
|
if ( dCurrLen > dLenMain)
|
|
dCurrLen -= dLenMain ;
|
|
bOk = ( pCrvMainEdge->GetParamAtLength( dCurrLen, dUInterpMain) &&
|
|
pCrvMainEdge->GetPointD1D2( dUInterpMain, ICurve::FROM_MINUS, ptInterpOnMain)) ;
|
|
if ( bOk) {
|
|
double dMagnitude = dLenLine2 + ( dI / ( nStep - 1)) * ( dLenLineInterpE - dLenLine2) ;
|
|
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
|
bOk = ( ! IsNull( pLine) && pLine->Set( ptInterpOnMain, ptInterpOnMain + vtInterp * dMagnitude)) ;
|
|
if ( bOk) {
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pLine)) ;
|
|
bOk = ( nNewId != GDB_ID_NULL) ;
|
|
if ( bOk)
|
|
nInterpEndId = nNewId ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtTrimmingGetToolOrientationLines(" + ToString( nParentId) + "," +
|
|
ToString( nMainEdgeId) + "," +
|
|
ToString( nOtherEdgeId) + "," +
|
|
ToString( nLineSId) + "," +
|
|
ToString( nLineEId) + "," +
|
|
ToString( dThetaStart) + "," +
|
|
ToString( dPhiStart) + "," +
|
|
ToString( dThetaEnd) + "," +
|
|
ToString( dPhiEnd) + "," +
|
|
ToString( dLinTol) + "," +
|
|
ToString( dInterpLenS) + "," +
|
|
ToString( dInterpLenE) + "," +
|
|
" -- bOk=" + ToString( bOk) +
|
|
" -- nInterpStartId=" + ToString( nInterpStartId) + ", nStartId=" + ToString( nStartId) +
|
|
", nEndId=" + ToString( nEndId) + ", nInterpEndId=" + ToString( nInterpEndId) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
struct TrimmingInterval {
|
|
double dLenStart ;
|
|
double dLenEnd ;
|
|
Vector3d vtStart ;
|
|
Vector3d vtEnd ;
|
|
TrimmingInterval()
|
|
: dLenStart( - EPS_SMALL), dLenEnd( - EPS_SMALL), vtStart( V_INVALID), vtEnd( V_INVALID) {} ;
|
|
TrimmingInterval( double dLenS, double dLenE, const Vector3d& vtS, const Vector3d& vtE)
|
|
: dLenStart( dLenS), dLenEnd( dLenE), vtStart( vtS), vtEnd( vtE) {} ;
|
|
} ;
|
|
typedef vector<TrimmingInterval> TRIMMINGINTERVALVECTOR ;
|
|
// ---------------------------------------------------------------------------
|
|
bool
|
|
GetTrimmingInterval( const IGeomDB* pGeomDB, const ICurveComposite* pCompo, const Frame3d& frCompo, int nIdS, int nIdE, bool bInvert, TrimmingInterval& TrimmingInt)
|
|
{
|
|
// Verifico validità dei parametri
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
if ( pCompo == nullptr || ! pCompo->IsValid() || ! frCompo.IsValid())
|
|
return false ;
|
|
|
|
// Recupero le linee di Orienting
|
|
const ICurve* pGeoCrvS = GetCurve( pGeomDB->GetGeoObj( nIdS)) ;
|
|
const ICurve* pGeoCrvE = GetCurve( pGeomDB->GetGeoObj( nIdE)) ;
|
|
if ( pGeoCrvS != nullptr && pGeoCrvE != nullptr && pGeoCrvS->IsValid() && pGeoCrvE->IsValid()) {
|
|
// Recupero i punti base ches stanno sulla pCompo e i vettori direzioni ( sono ICurveLine*, ma le tratto come ICurve* generiche)
|
|
Point3d ptS = P_INVALID ;
|
|
Point3d ptE = P_INVALID ;
|
|
if ( ! bInvert) {
|
|
pGeoCrvS->GetStartPoint( ptS) ; // Line1.ptStart
|
|
pGeoCrvE->GetStartPoint( ptE) ; // Line2.ptStart
|
|
}
|
|
else {
|
|
pGeoCrvS->GetEndPoint( ptS) ;
|
|
pGeoCrvE->GetEndPoint( ptE) ;
|
|
}
|
|
Vector3d vtS = V_INVALID ; pGeoCrvS->GetStartDir( vtS) ; // Line1.vtStart
|
|
Vector3d vtE = V_INVALID ; pGeoCrvE->GetStartDir( vtE) ; // Line2.vtStart
|
|
if ( ptS.IsValid() && ptE.IsValid() && vtS.IsValid() && vtE.IsValid()) {
|
|
// Recupero il Frame delle Linee
|
|
Frame3d frCrv1, frCrv2 ;
|
|
if ( ! pGeomDB->GetGlobFrame( nIdS, frCrv1) || ! pGeomDB->GetGlobFrame( nIdE, frCrv2))
|
|
return false ;
|
|
// Porto Tali valori nel riferimento dalla Composita
|
|
Point3d ptSLoc = GetLocToLoc( ptS, frCrv1, frCompo) ;
|
|
Point3d ptELoc = GetLocToLoc( ptE, frCrv2, frCompo) ;
|
|
Vector3d vtSLoc = GetLocToLoc( vtS, frCrv1, frCompo) ;
|
|
Vector3d vtELoc = GetLocToLoc( vtE, frCrv2, frCompo) ;
|
|
// Recupero il parametro sulla curva
|
|
double dParS = - EPS_PARAM, dParE = - EPS_PARAM ;
|
|
int nFlag = 0 ;
|
|
if ( DistPointCurve( ptSLoc, *pCompo).GetParamAtMinDistPoint( EPS_SMALL, dParS, nFlag) &&
|
|
DistPointCurve( ptELoc, *pCompo).GetParamAtMinDistPoint( EPS_SMALL, dParE, nFlag)) {
|
|
// Recupero la lunghezza su tale curva
|
|
double dLenS = - EPS_SMALL, dLenE = - EPS_SMALL ;
|
|
if ( pCompo->GetLengthAtParam( dParS, dLenS) && pCompo->GetLengthAtParam( dParE, dLenE)) {
|
|
TrimmingInt = TrimmingInterval( dLenS, dLenE, vtSLoc, vtELoc) ;
|
|
return true ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false ;
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
bool
|
|
Exe5AxTrimmingModifyToolDir( int nCrvId, int nPathId, int nTrimLayId, const INTVECTOR& vnOrientingId, const INTVECTOR& vnOrientingISId,
|
|
const INTVECTOR& vnOrientingSId, const INTVECTOR& vnOrientingEId, const INTVECTOR& vnOrientingIEId)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
|
|
// Verifico validità dei parametri
|
|
bool bOk = ( nCrvId != GDB_ID_NULL && nPathId != GDB_ID_NULL && nTrimLayId != GDB_ID_NULL &&
|
|
ssize( vnOrientingId) == ssize( vnOrientingISId) && ssize( vnOrientingISId) == ssize( vnOrientingSId) &&
|
|
ssize( vnOrientingSId) == ssize( vnOrientingEId) && ssize( vnOrientingEId) == ssize( vnOrientingIEId)) ;
|
|
|
|
// Recupero la curva di Bordo e la sua composit associata
|
|
const ICurve* pCrvBorder = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ;
|
|
bOk = bOk && ( pCrvBorder != nullptr && pCrvBorder->IsValid()) ;
|
|
PtrOwner<ICurveComposite> pCompoBorder( nullptr) ;
|
|
if ( bOk)
|
|
bOk = ( pCompoBorder.Set( ConvertCurveToComposite( pCrvBorder->Clone())) && pCompoBorder->IsValid()) ;
|
|
double dLen = - EPS_SMALL ;
|
|
if ( bOk)
|
|
bOk = pCompoBorder->GetLength( dLen) ;
|
|
|
|
// Recupero il Frame della curva corrente
|
|
Frame3d frCompo ;
|
|
bOk = bOk && ( pGeomDB->GetGlobFrame( nCrvId, frCompo)) ;
|
|
|
|
bool bInvert = false ;
|
|
if ( ssize( vnOrientingISId) > 0 && vnOrientingISId[0] != GDB_ID_NULL) {
|
|
const ICurve* pGeoCrvS = GetCurve( pGeomDB->GetGeoObj( vnOrientingISId[0])) ;
|
|
Point3d ptS ; pGeoCrvS->GetStartPoint( ptS) ;
|
|
double dDist = 1 ;
|
|
if ( DistPointCurve( ptS, *pCompoBorder).GetDist( dDist) && dDist > EPS_SMALL)
|
|
bInvert = true ;
|
|
}
|
|
|
|
// Recupero i versori di interpolazione e creo dei gruppi
|
|
TRIMMINGINTERVALVECTOR vInterval ; vInterval.reserve( 3 * ssize( vnOrientingId)) ;
|
|
for ( int i = 0 ; bOk && i < ssize( vnOrientingId) ; ++ i) {
|
|
// Se presente Interpolazione iniziale
|
|
if ( vnOrientingISId[i] != GDB_ID_NULL && vnOrientingSId[i] != GDB_ID_NULL) {
|
|
TrimmingInterval myTrimInt ;
|
|
if ( GetTrimmingInterval( pGeomDB, pCompoBorder, frCompo, vnOrientingISId[i], vnOrientingSId[i], bInvert, myTrimInt))
|
|
vInterval.emplace_back( myTrimInt) ;
|
|
}
|
|
// Interpolazione ( deve essere sempre presente, ma per scrupolo si controlla lo stesso)
|
|
if ( vnOrientingSId[i] != GDB_ID_NULL && vnOrientingEId[i] != GDB_ID_NULL) {
|
|
TrimmingInterval myTrimInt ;
|
|
if ( GetTrimmingInterval( pGeomDB, pCompoBorder, frCompo, vnOrientingSId[i], vnOrientingEId[i], bInvert, myTrimInt))
|
|
vInterval.emplace_back( myTrimInt) ;
|
|
}
|
|
// Se presente Interpolazione finale
|
|
if ( vnOrientingEId[i] != GDB_ID_NULL && vnOrientingIEId[i] != GDB_ID_NULL) {
|
|
TrimmingInterval myTrimInt ;
|
|
if ( GetTrimmingInterval( pGeomDB, pCompoBorder, frCompo, vnOrientingEId[i], vnOrientingIEId[i], bInvert, myTrimInt))
|
|
vInterval.emplace_back( myTrimInt) ;
|
|
}
|
|
}
|
|
|
|
// Se ho degli intervalli di Interpolazione
|
|
if ( ! vInterval.empty()) {
|
|
// Scorro i vettori presenti nel Layer ausiliario della lavorazione
|
|
int nId = pGeomDB->GetFirstInGroup( nPathId) ;
|
|
while ( bOk && nId != GDB_ID_NULL) {
|
|
IGeoVector3d* vGeo = GetGeoVector3d( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( vGeo != nullptr && vGeo->IsValid()) {
|
|
// Recupero i parametri di tale vettore
|
|
Point3d ptBase = vGeo->GetBase() ;
|
|
Vector3d vtDirV = V_INVALID ; ;
|
|
if ( pGeomDB->GetInfo( nId, "DirV", vtDirV) && vtDirV.IsValid()) {
|
|
// Recupero la lunghezza associata al Punto di Base sulla Compo
|
|
double dCurrPar = - EPS_SMALL ;
|
|
int nFlag = 0 ;
|
|
if ( DistPointCurve( ptBase, *pCompoBorder).GetParamAtMinDistPoint( 0., dCurrPar, nFlag)) {
|
|
double dCurrLen = - EPS_SMALL ;
|
|
if ( pCompoBorder->GetLengthAtParam( dCurrPar, dCurrLen)) {
|
|
for ( const TrimmingInterval& CurrInterval : vInterval) {
|
|
// Controlli per Intervalli a cavallo dei punti iniziali e finali della curva
|
|
double dLenA = CurrInterval.dLenStart ;
|
|
double dLenB = CurrInterval.dLenEnd ;
|
|
double dLenC = dCurrLen ;
|
|
if ( dLenA > dLenB) {
|
|
dLenB += dLen ;
|
|
if ( dLenC < CurrInterval.dLenStart - EPS_SMALL)
|
|
dLenC += dLen ;
|
|
}
|
|
// Se l'intervallo non è troppo piccolo e se sono all'interno di tale Intervallo
|
|
if ( dLenB - dLenA > 10. * EPS_SMALL && /* bastava anche 2 * EPS_SMALL */
|
|
dLenA + EPS_SMALL < dLenC && dLenC < dLenB + EPS_SMALL /* estremi esclusi, va bene ? */) {
|
|
// Media pesata dei due vettori
|
|
double dMeanPar = ( dLenC - dLenA) / ( dLenB - dLenA) ;
|
|
Vector3d vtMean = Media( CurrInterval.vtStart, CurrInterval.vtEnd, dMeanPar) ;
|
|
// Assegno la Info a tale vettore
|
|
pGeomDB->SetInfo( nId, "DirV", vtMean) ;
|
|
break ; // non controllo altri intervalli
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
nId = pGeomDB->GetNext( nId) ;
|
|
}
|
|
}
|
|
|
|
ExeSetModified() ;
|
|
// Se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtTrimmingGetToolOrientationLines(" + ToString( nCrvId) + "," +
|
|
ToString( nPathId) + "," +
|
|
ToString( nTrimLayId) + "," +
|
|
ToString( vnOrientingId) + "," +
|
|
ToString( vnOrientingISId) + "," +
|
|
ToString( vnOrientingSId) + "," +
|
|
ToString( vnOrientingEId) + "," +
|
|
ToString( vnOrientingIEId) + "," +
|
|
" -- bOk=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
int
|
|
ExeRegolarizeSurfaceLocally( int nParentId, int nSurfId, int nSyncStartId, int nSyncEndId, double dLinTol, int nType)
|
|
{
|
|
// Verifica database geometrico
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
|
|
// recupero la superficie
|
|
ISurfBezier* pSurfBez = GetSurfBezier( GetSurf( pGeomDB->GetGeoObj( nSurfId))) ;
|
|
|
|
// recupero le due isocurve
|
|
const ICurve* pSyncStart = GetCurveLine( GetCurve( pGeomDB->GetGeoObj( nSyncStartId))) ;
|
|
const ICurve* pSyncEnd = GetCurveLine( GetCurve( pGeomDB->GetGeoObj( nSyncEndId))) ;
|
|
Point3d ptS1 ; pSyncStart->GetStartPoint( ptS1) ;
|
|
Point3d ptE1 ; pSyncStart->GetEndPoint( ptE1) ;
|
|
BIPOINT bpIsoStart( ptS1, ptE1) ;
|
|
Point3d ptS2 ; pSyncEnd->GetStartPoint( ptS2) ;
|
|
Point3d ptE2 ; pSyncEnd->GetEndPoint( ptE2) ;
|
|
BIPOINT bpIsoEnd( ptS2, ptE2) ;
|
|
|
|
PtrOwner<ISurfBezier> pNewSurf( RegolarizeBordersLocally( pSurfBez, bpIsoStart, bpIsoEnd, dLinTol, nType)) ;
|
|
if ( IsNull( pNewSurf))
|
|
return GDB_ID_NULL ;
|
|
int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pNewSurf)) ;
|
|
|
|
return nId ;
|
|
} |