6f8e37c9ee
- aggiunto funioni alla IntersCurveCurve per filtrare le intersezioni 3D.
1484 lines
59 KiB
C++
1484 lines
59 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2018-2018
|
|
//----------------------------------------------------------------------------
|
|
// File : EXE_GeoInters.cpp Data : 27.09.18 Versione : 1.9i4
|
|
// Contenuto : Funzioni di intersezioni tra oggetto geometrici per EXE.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 27.09.18 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/EGkCurveLine.h"
|
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkChainCurves.h"
|
|
#include "/EgtDev/Include/EGkCurveLocal.h"
|
|
#include "/EgtDev/Include/EGkStmStandard.h"
|
|
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
|
#include "/EgtDev/Include/EGkSurfLocal.h"
|
|
#include "/EgtDev/Include/EGkVolZmap.h"
|
|
#include "/EgtDev/Include/EGkIntersLineBox.h"
|
|
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
|
#include "/EgtDev/Include/EGkIntersLineVolZmap.h"
|
|
#include "/EgtDev/Include/EGkIntersPlaneBox.h"
|
|
#include "/EgtDev/Include/EGkIntersLineSurfBez.h"
|
|
#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h"
|
|
#include "/EgtDev/Include/EGkIntersPlaneVolZmap.h"
|
|
#include "/EgtDev/Include/EGkIntersCurves.h"
|
|
#include "/EgtDev/Include/EGkIntersCurveSurfTm.h"
|
|
#include "/EgtDev/Include/EGkIntersSurfTmSurfTm.h"
|
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
|
|
using namespace std ;
|
|
|
|
//-------------------------------------------------------------------------------
|
|
bool
|
|
MyLineCurveInters( const Point3d& ptP, const Vector3d& vtDir, const int nId, const int nRefType,
|
|
INTDBLVECTOR& vInters)
|
|
{
|
|
vInters.clear() ;
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero il riferimento di calcolo
|
|
Frame3d frCalc ;
|
|
if ( nRefType == RTY_GLOB)
|
|
frCalc = GLOB_FRM ;
|
|
else if ( nRefType == RTY_GRID)
|
|
frCalc = pGeomDB->GetGridFrame() ;
|
|
else {
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frCalc))
|
|
return false ;
|
|
}
|
|
// recupero la curva in locale al gruppo destinazione
|
|
CurveLocal CrvLoc( pGeomDB, nId, frCalc) ;
|
|
// calcolo l'ingombro della curva
|
|
BBox3d b3Crv ;
|
|
if ( ! CrvLoc->GetLocalBBox( b3Crv))
|
|
return false ;
|
|
b3Crv.Expand( 100 * EPS_SMALL) ;
|
|
// definisco la linea (punto e direzione sono gi� nel riferimento di calcolo)
|
|
double dLen = 2 * floor( b3Crv.MaxDistFromPoint( ptP)) ;
|
|
double dOffs = -dLen / 2 ;
|
|
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
|
if ( IsNull( pLine) || ! pLine->SetPVL( ptP + dOffs * vtDir, vtDir, dLen) )
|
|
return false ;
|
|
// intersezione fra le curve nel piano di calcolo
|
|
IntersCurveCurve intCC( *pLine, *CrvLoc, true) ;
|
|
int nInters = intCC.GetIntersCount() ;
|
|
// recupero i risultati
|
|
for ( int i = 0 ; i < nInters ; i++) {
|
|
IntCrvCrvInfo aInfo ;
|
|
intCC.GetIntCrvCrvInfo( i, aInfo) ;
|
|
// se intersezione puntuale
|
|
if ( ! aInfo.bOverlap) {
|
|
double dDist = dOffs + aInfo.IciA[0].dU * dLen ;
|
|
int nType = CLT_NONE ;
|
|
if ( aInfo.IciA[0].nPrevTy == ICCT_IN) {
|
|
if ( aInfo.IciA[0].nNextTy == ICCT_IN)
|
|
nType = CLT_TOUCH_IN ;
|
|
else if ( aInfo.IciA[0].nNextTy == ICCT_OUT)
|
|
nType = CLT_OUT ;
|
|
}
|
|
else if ( aInfo.IciA[0].nPrevTy == ICCT_OUT) {
|
|
if ( aInfo.IciA[0].nNextTy == ICCT_IN)
|
|
nType = CLT_IN ;
|
|
else if ( aInfo.IciA[0].nNextTy == ICCT_OUT)
|
|
nType = CLT_TOUCH_OUT ;
|
|
}
|
|
vInters.emplace_back( nType, dDist) ;
|
|
}
|
|
// altrimenti sovrapposizione
|
|
else {
|
|
// inizio
|
|
double dDist1 = dOffs + aInfo.IciA[0].dU * dLen ;
|
|
int nType1 = CLT_NONE ;
|
|
if ( aInfo.IciA[0].nPrevTy == ICCT_IN)
|
|
nType1 = CLT_TGINI_IN ;
|
|
else if ( aInfo.IciA[0].nPrevTy == ICCT_OUT)
|
|
nType1 = CLT_TGINI_OUT ;
|
|
vInters.emplace_back( nType1, dDist1) ;
|
|
// fine
|
|
double dDist2 = dOffs + aInfo.IciA[1].dU * dLen ;
|
|
int nType2 = CLT_NONE ;
|
|
if ( aInfo.IciA[1].nNextTy == ICCT_IN)
|
|
nType2 = CLT_TGFIN_IN ;
|
|
else if ( aInfo.IciA[1].nNextTy == ICCT_OUT)
|
|
nType2 = CLT_TGFIN_OUT ;
|
|
vInters.emplace_back( nType2, dDist2) ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
bool
|
|
ExeLineCurveInters( const Point3d& ptP, const Vector3d& vtDir, const int nId, const int nRefType,
|
|
INTDBLVECTOR& vInters)
|
|
{
|
|
// eseguo
|
|
bool bOk = MyLineCurveInters( ptP, vtDir, nId, nRefType, vInters) ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtLineCurveInters({" + ToString( ptP) + "},{" +
|
|
ToString( vtDir) + "},{" +
|
|
ToString( nId) + "," +
|
|
RefTypeToString( nRefType) + ")" +
|
|
" -- Ok=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
// restituisco stato esecuzione
|
|
return bOk ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
bool
|
|
ExeLineBoxInters( const Point3d& ptP, const Vector3d& vtDir, const BBox3d& b3Box,
|
|
INTDBLVECTOR& vInters)
|
|
{
|
|
// eseguo
|
|
bool bOk = IntersLineBox( ptP, vtDir, 1, b3Box, vInters, false) ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtLineBoxInters({" + ToString( ptP) + "},{" +
|
|
ToString( vtDir) + "},{" +
|
|
ToString( b3Box) + "})" +
|
|
" -- Ok=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return bOk ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static bool
|
|
MyLineSurfTmInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType,
|
|
INTDBLVECTOR& vInters)
|
|
{
|
|
vInters.clear() ;
|
|
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 suo riferimento globale
|
|
Frame3d frSurf ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frSurf))
|
|
return false ;
|
|
// porto in locale il punto e la direzione della linea
|
|
Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frSurf) ;
|
|
Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frSurf) ;
|
|
vtDirL.Normalize() ;
|
|
// calcolo l'ingombro della trimesh
|
|
BBox3d b3Surf ;
|
|
if ( ! pStm->GetLocalBBox( b3Surf))
|
|
return false ;
|
|
// calcolo l'intersezione
|
|
double dLen = b3Surf.MaxDistFromPoint( ptPL) ;
|
|
ILSIVECTOR vInfo ;
|
|
if ( ! IntersLineSurfTm( ptPL, vtDirL, dLen, *pStm, vInfo, false))
|
|
return false ;
|
|
|
|
// filtro le intersezioni
|
|
FilterLineSurfTmInters( vInfo, vInters) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
bool
|
|
ExeLineSurfTmInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType,
|
|
INTDBLVECTOR& vInters)
|
|
{
|
|
// eseguo
|
|
bool bOk = MyLineSurfTmInters( ptP, vtDir, nId, nRefType, vInters) ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtLineSurfTmInters({" + ToString( ptP) + "},{" +
|
|
ToString( vtDir) + "}," +
|
|
ToString( nId) + "," +
|
|
RefTypeToString( nRefType) + ")" +
|
|
" -- Ok=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return bOk ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static bool
|
|
MyLineSurfBzInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType, INTDBLVECTOR& vInters)
|
|
{
|
|
vInters.clear() ;
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero la superficie Bezier
|
|
const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pSbz == nullptr)
|
|
return false ;
|
|
// recupero il suo riferimento globale
|
|
Frame3d frSurf ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frSurf))
|
|
return false ;
|
|
// porto in locale il punto e la direzione della linea
|
|
Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frSurf) ;
|
|
Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frSurf) ;
|
|
vtDirL.Normalize() ;
|
|
// calcolo l'ingombro della Bezier
|
|
BBox3d b3Surf ;
|
|
if ( ! pSbz->GetLocalBBox( b3Surf))
|
|
return false ;
|
|
// calcolo l'intersezione
|
|
double dLen = b3Surf.MaxDistFromPoint( ptPL) ;
|
|
ILSBIVECTOR vInfo ;
|
|
if ( ! IntersLineSurfBz( ptPL, vtDirL, dLen, pSbz, vInfo, false))
|
|
return false ;
|
|
|
|
// filtro le intersezioni
|
|
FilterLineSurfBzInters( vInfo, vInters) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
bool
|
|
ExeLineSurfBzInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType,
|
|
INTDBLVECTOR& vInters)
|
|
{
|
|
// eseguo
|
|
bool bOk = MyLineSurfBzInters( ptP, vtDir, nId, nRefType, vInters) ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtLineSurfBzInters({" + ToString( ptP) + "},{" +
|
|
ToString( vtDir) + "}," +
|
|
ToString( nId) + "," +
|
|
RefTypeToString( nRefType) + ")" +
|
|
" -- Ok=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return bOk ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static bool
|
|
MyLineVolZmapInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType,
|
|
INTDBLVECTOR& vInters)
|
|
{
|
|
vInters.clear() ;
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero lo Zmap
|
|
IVolZmap* pVZM = GetVolZmap( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pVZM == nullptr)
|
|
return false ;
|
|
// recupero il suo riferimento globale
|
|
Frame3d frZmap ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frZmap))
|
|
return false ;
|
|
// porto in locale il punto e la direzione della linea
|
|
Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frZmap) ;
|
|
Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frZmap) ;
|
|
vtDirL.Normalize() ;
|
|
// calcolo l'intersezione
|
|
ILZIVECTOR vInfo ;
|
|
if ( ! IntersLineVolZmap( ptPL, vtDirL, *pVZM, vInfo))
|
|
return false ;
|
|
|
|
// filtro le intersezioni
|
|
FilterLineVolZmapInters( vInfo, vInters) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
bool
|
|
ExeLineVolZmapInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType,
|
|
INTDBLVECTOR& vInters)
|
|
{
|
|
// eseguo
|
|
bool bOk = MyLineVolZmapInters( ptP, vtDir, nId, nRefType, vInters) ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtLineVolZmapInters({" + ToString( ptP) + "},{" +
|
|
ToString( vtDir) + "}," +
|
|
ToString( nId) + "," +
|
|
RefTypeToString( nRefType) + ")" +
|
|
" -- Ok=" + ToString( bOk) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco stato operazione
|
|
return bOk ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static int
|
|
MyAddPlaneIntersResultToGeomDB( IGeomDB* pGeomDB, const PNTVECTOR& vPnt, const BIPNTVECTOR& vBpt, const TRIA3DVECTOR& vTria,
|
|
const Frame3d& frOrig, const Frame3d& frDest, int nId, int nDestGrpId, const Vector3d& vtExtr,
|
|
double dToler, int& nPntCount, int& nCrvCount, int& nSrfCount)
|
|
{
|
|
// Inserisco il risultato nel DB
|
|
int nFirstId = GDB_ID_NULL ;
|
|
// Inserisco i punti nel DB
|
|
for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) {
|
|
// creo il punto
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
if ( IsNull( pGeoPnt))
|
|
return GDB_ID_NULL ;
|
|
// setto il punto
|
|
pGeoPnt->Set( vPnt[i]) ;
|
|
// porto il punto nel riferimento destinazione
|
|
pGeoPnt->LocToLoc( frOrig, frDest) ;
|
|
// lo inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nPntCount ;
|
|
}
|
|
// Inserisco le curve nel DB (dopo averle concatenate)
|
|
ChainCurves chainC ;
|
|
chainC.Init( false, dToler, int( vBpt.size())) ;
|
|
for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) {
|
|
Vector3d vtDir = vBpt[i].second - vBpt[i].first ;
|
|
vtDir.Normalize() ;
|
|
if ( ! chainC.AddCurve( i + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir))
|
|
return GDB_ID_NULL ;
|
|
}
|
|
// recupero i percorsi concatenati
|
|
Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ;
|
|
INTVECTOR vId ;
|
|
while ( chainC.GetChainFromNear( ptNear, false, vId)) {
|
|
// creo una curva composita
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvCompo))
|
|
return GDB_ID_NULL ;
|
|
// recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita
|
|
bool bAdded = true ;
|
|
for ( int i = 0 ; i < int( vId.size()) ; ++ i) {
|
|
// creo un segmento di retta
|
|
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
|
if ( IsNull( pLine))
|
|
return GDB_ID_NULL ;
|
|
// recupero gli estremi (non vanno mai invertiti per opzione di concatenamento)
|
|
int nInd = abs( vId[i]) - 1 ;
|
|
Point3d ptStart = ( bAdded ? vBpt[nInd].first : ptNear) ;
|
|
Point3d ptEnd = vBpt[nInd].second ;
|
|
// provo ad accodarlo alla composita
|
|
bAdded = ( Dist( ptStart, ptEnd) > dToler / 2 &&
|
|
pLine->Set( ptStart, ptEnd) &&
|
|
pCrvCompo->AddCurve( Release( pLine), true, dToler)) ;
|
|
ptNear = ( bAdded ? ptEnd : ptStart) ;
|
|
}
|
|
// se lunghezza curva inferiore a 5 volte la tolleranza, la ignoro
|
|
double dCrvLen ;
|
|
if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5. * dToler)
|
|
continue ;
|
|
// se curva chiusa entro 5 volte la tolleranza ma considerata aperta, la chiudo bene
|
|
Point3d ptStart, ptEnd ;
|
|
if ( pCrvCompo->GetStartPoint( ptStart) &&
|
|
pCrvCompo->GetEndPoint( ptEnd) &&
|
|
AreSamePointEpsilon( ptStart, ptEnd, 5. * dToler) &&
|
|
! AreSamePointApprox( ptStart, ptEnd)) {
|
|
// porto il punto finale a coincidere esattamente con l'inizio
|
|
pCrvCompo->ModifyEnd( ptStart) ;
|
|
}
|
|
// assegno estrusione come direzione normale al piano
|
|
pCrvCompo->SetExtrusion( vtExtr) ;
|
|
// unisco segmenti allineati
|
|
pCrvCompo->MergeCurves( 0.5 * dToler, ANG_TOL_STD_DEG) ;
|
|
// porto la curva nel riferimento destinazione
|
|
pCrvCompo->LocToLoc( frOrig, frDest) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nCrvCount ;
|
|
}
|
|
// Inserisco i triangoli nel DB (dopo averli uniti in una superficie trimesh)
|
|
StmFromTriangleSoup StmFts ;
|
|
if ( ! StmFts.Start())
|
|
return GDB_ID_NULL ;
|
|
for ( int i = 0 ; i < int( vTria.size()) ; ++ i)
|
|
// inserisco il triangolo nella nuova superficie
|
|
StmFts.AddTriangle( vTria[i]) ;
|
|
// valido la superficie e calcolo le adiacenze
|
|
if ( ! StmFts.End())
|
|
return GDB_ID_NULL ;
|
|
// se superficie con triangoli
|
|
PtrOwner<ISurfTriMesh> pNewStm( StmFts.GetSurf()) ;
|
|
if ( ! IsNull( pNewStm) && pNewStm->GetTriangleCount() > 0) {
|
|
// porto la superficie nel riferimento destinazione
|
|
pNewStm->LocToLoc( frOrig, frDest) ;
|
|
// la inserisco nel DB
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pNewStm)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nSrfCount ;
|
|
}
|
|
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
MyPlaneCurveInters( const Point3d& ptOn, const Vector3d& vtN, const int nId, const int nDestGrpId, const int nRefType, int& nCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la curva
|
|
const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pCrv == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// recupero il suo riferimento globale
|
|
Frame3d frCrv ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frCrv))
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
|
|
// definisco il piano in locale
|
|
Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frCrv) ;
|
|
Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frCrv) ;
|
|
Plane3d plPlane ;
|
|
plPlane.Set( ptOnL, vtNL) ;
|
|
|
|
// approssimo la curva con polyline
|
|
PolyLine PL ;
|
|
if ( ! pCrv->ApproxWithLines( 10 * EPS_SMALL, 15, ICurve::APL_SPECIAL, PL))
|
|
return GDB_ID_NULL ;
|
|
|
|
// per ogni tratto della polyline cerco l'intersezione con il piano
|
|
PNTVECTOR vPnt ;
|
|
BIPNTVECTOR vBpt ;
|
|
Point3d ptS, ptE ;
|
|
PL.GetFirstPoint( ptS) ;
|
|
while ( PL.GetNextPoint( ptE)) {
|
|
Point3d ptInt ;
|
|
int nRes = IntersLinePlane( ptS, ptE, plPlane, ptInt) ;
|
|
if ( nRes == ILPT_INPLANE)
|
|
vBpt.emplace_back( ptS, ptE) ;
|
|
else if ( nRes != ILPT_NO)
|
|
vPnt.emplace_back( ptInt) ;
|
|
// aggiorno ptS per tratto successivo
|
|
ptS = ptE ;
|
|
}
|
|
|
|
// elimino segmenti ripetuti
|
|
for ( int i = 0 ; i < ( int)vBpt.size() ; ) {
|
|
bool bFound = false ;
|
|
for ( int j = i + 1 ; j < ( int)vBpt.size() ; j ++) {
|
|
if (( AreSamePointApprox( vBpt[i].first, vBpt[j].first) && AreSamePointApprox( vBpt[i].second, vBpt[j].second)) ||
|
|
( AreSamePointApprox( vBpt[i].first, vBpt[j].second) && AreSamePointApprox( vBpt[i].second, vBpt[j].first))) {
|
|
bFound = true ;
|
|
break ;
|
|
}
|
|
}
|
|
if ( bFound)
|
|
vBpt.erase( vBpt.begin() + i) ;
|
|
else
|
|
i ++ ;
|
|
}
|
|
|
|
// elimino punti ripetuti
|
|
for ( int i = 0 ; i < ( int)vPnt.size() ; ) {
|
|
bool bFound = false ;
|
|
// cerco tra i punti rimanenti
|
|
for ( int j = i + 1 ; j < ( int)vPnt.size() ; j ++) {
|
|
if ( AreSamePointApprox( vPnt[i], vPnt[j])) {
|
|
bFound = true ;
|
|
break ;
|
|
}
|
|
}
|
|
// cerco eventualmente tra i segmenti
|
|
if ( ! bFound) {
|
|
for ( int j = 0 ; j < ( int)vBpt.size() ; j ++) {
|
|
if ( AreSamePointApprox( vPnt[i], vBpt[j].first) || AreSamePointApprox( vPnt[i], vBpt[j].second)) {
|
|
bFound = true ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
if ( bFound)
|
|
vPnt.erase( vPnt.begin() + i) ;
|
|
else
|
|
i ++ ;
|
|
}
|
|
|
|
// aggiungo i risultati al DB geometrico
|
|
int nPntCount{ 0}, nCrvCount{ 0}, nTmp{ 0} ;
|
|
int nFirstId = MyAddPlaneIntersResultToGeomDB( pGeomDB, vPnt, vBpt, TRIA3DVECTOR(), frCrv, frDest, nId, nDestGrpId, vtNL,
|
|
EPS_SMALL, nPntCount, nCrvCount, nTmp) ;
|
|
nCount = nPntCount + nCrvCount ;
|
|
|
|
// restituisco l'identificativo della prima entit� creata
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
ExePlaneCurveInters( const Point3d& ptOn, const Vector3d& vtN, const int nId, const int nDestGrpId, const int nRefType, int* pnCount)
|
|
{
|
|
// eseguo
|
|
int nCount{ 0} ;
|
|
int nFirstId = MyPlaneCurveInters( ptOn, vtN, nId, nDestGrpId, nRefType, nCount) ;
|
|
// aggiorno contatori
|
|
if ( nFirstId != GDB_ID_NULL) {
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
ExeSetModified() ;
|
|
}
|
|
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtPlaneCurveInters({" + ToString( ptOn) + "},{" +
|
|
ToString( vtN) + "},{" +
|
|
ToString( nId) + "," +
|
|
ToString( nDestGrpId) + "," +
|
|
RefTypeToString( nRefType) + ")" +
|
|
" -- Id=" + ToString( nFirstId) + ", nCnt=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static int
|
|
MyPlaneBoxInters( const Point3d& ptOn, const Vector3d& vtN, const BBox3d& b3Box, int nDestGrpId, int nRefType,
|
|
int& nPntCount, int& nCrvCount, int& nSrfCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento sorgente
|
|
Frame3d frSou ;
|
|
if ( nRefType == RTY_GLOB)
|
|
frSou = Frame3d() ;
|
|
else if ( nRefType == RTY_GRID)
|
|
frSou = pGeomDB->GetGridFrame() ;
|
|
else // ( nRefType == RTY_LOC)
|
|
frSou = frDest ;
|
|
// calcolo il piano
|
|
Plane3d plPlane ;
|
|
if ( ! plPlane.Set( ptOn, vtN))
|
|
return GDB_ID_NULL ;
|
|
// eseguo l'intersezione
|
|
PNTVECTOR vPnt ;
|
|
BIPNTVECTOR vBpt ;
|
|
TRIA3DVECTOR vTria ;
|
|
if ( ! IntersPlaneBox( plPlane, b3Box, vPnt, vBpt, vTria))
|
|
return GDB_ID_NULL ;
|
|
// porto le intersezioni nel riferimento destinazione
|
|
for ( auto& Pnt : vPnt)
|
|
Pnt.LocToLoc( frSou, frDest) ;
|
|
for ( auto& Bpt : vBpt) {
|
|
Bpt.first.LocToLoc( frSou, frDest) ;
|
|
Bpt.second.LocToLoc( frSou, frDest) ;
|
|
}
|
|
for ( auto& Tria : vTria)
|
|
Tria.LocToLoc( frSou, frDest) ;
|
|
// porto la normale al piano nel riferimento destinazione
|
|
Vector3d vtNL = vtN ;
|
|
vtNL.LocToLoc( frSou, frDest) ;
|
|
// Inserisco il risultato nel DB
|
|
int nFirstId = GDB_ID_NULL ;
|
|
// Inserisco i punti nel DB
|
|
for ( size_t i = 0 ; i < vPnt.size() ; ++ i) {
|
|
// creo il punto
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
if ( IsNull( pGeoPnt))
|
|
return GDB_ID_NULL ;
|
|
// setto il punto
|
|
pGeoPnt->Set( vPnt[i]) ;
|
|
// lo inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nPntCount ;
|
|
}
|
|
// Concateno i tratti di curva
|
|
double dToler = 2 * EPS_SMALL ;
|
|
ChainCurves chainC ;
|
|
chainC.Init( false, dToler, int( vBpt.size())) ;
|
|
for ( size_t i = 0 ; i < vBpt.size() ; ++ i) {
|
|
Vector3d vtDir = vBpt[i].second - vBpt[i].first ;
|
|
vtDir.Normalize() ;
|
|
if ( ! chainC.AddCurve( int( i) + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir))
|
|
return GDB_ID_NULL ;
|
|
}
|
|
// recupero i percorsi concatenati
|
|
Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ;
|
|
INTVECTOR vId ;
|
|
while ( chainC.GetChainFromNear( ptNear, false, vId)) {
|
|
// creo una curva composita
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvCompo))
|
|
return GDB_ID_NULL ;
|
|
// recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita
|
|
for ( size_t i = 0 ; i < vId.size() ; ++ i) {
|
|
// creo una segmento di retta
|
|
int nInd = abs( vId[i]) - 1 ;
|
|
bool bInvert = ( vId[i] < 0) ;
|
|
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
|
if ( IsNull( pLine) || ! pLine->Set( vBpt[nInd].first, vBpt[nInd].second))
|
|
return GDB_ID_NULL ;
|
|
if ( bInvert)
|
|
pLine->Invert() ;
|
|
// lo accodo alla composita
|
|
if ( ! pCrvCompo->AddCurve( Release( pLine), true, dToler))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno il prossimo near
|
|
ptNear = vBpt[nInd].second ;
|
|
}
|
|
// se lunghezza curva inferiore a 5 volte la tolleranza, la salto
|
|
double dCrvLen ;
|
|
if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5. * dToler)
|
|
continue ;
|
|
// se curva chiusa entro 5 volte la tolleranza ma considerata aperta, la chiudo bene
|
|
Point3d ptStart, ptEnd ;
|
|
if ( pCrvCompo->GetStartPoint( ptStart) &&
|
|
pCrvCompo->GetEndPoint( ptEnd) &&
|
|
AreSamePointEpsilon( ptStart, ptEnd, 5. * dToler) &&
|
|
! AreSamePointApprox( ptStart, ptEnd)) {
|
|
// porto il punto finale a coincidere esattamente con l'inizio
|
|
pCrvCompo->ModifyEnd( ptStart) ;
|
|
}
|
|
// assegno estrusione come direzione normale al piano
|
|
pCrvCompo->SetExtrusion( vtNL) ;
|
|
// unisco segmenti allineati
|
|
pCrvCompo->MergeCurves( 0.5 * dToler, ANG_TOL_STD_DEG) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nCrvCount ;
|
|
}
|
|
// Se ci sono segmenti ma non sono state create curve, aggiungo punto nel loro centro
|
|
if ( ! vBpt.empty() && nCrvCount == 0) {
|
|
BBox3d b3Crv ;
|
|
for ( size_t i = 0 ; i < vBpt.size() ; ++ i) {
|
|
b3Crv.Add( vBpt[i].first) ;
|
|
b3Crv.Add( vBpt[i].second) ;
|
|
}
|
|
if ( ! b3Crv.IsEmpty()) {
|
|
// creo il punto
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
if ( IsNull( pGeoPnt))
|
|
return GDB_ID_NULL ;
|
|
// setto il punto
|
|
Point3d ptCen ; b3Crv.GetCenter( ptCen) ;
|
|
pGeoPnt->Set( ptCen) ;
|
|
// lo inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nPntCount ;
|
|
}
|
|
}
|
|
// Costruisco una superficie trimesh dall'insieme di triangoli
|
|
StmFromTriangleSoup StmFts ;
|
|
if ( ! StmFts.Start())
|
|
return GDB_ID_NULL ;
|
|
for ( size_t i = 0 ; i < vTria.size() ; ++ i)
|
|
// inserisco il triangolo nella nuova superficie
|
|
StmFts.AddTriangle( vTria[i]) ;
|
|
// valido la superficie e calcolo le adiacenze
|
|
if ( ! StmFts.End())
|
|
return GDB_ID_NULL ;
|
|
// se superficie con triangoli
|
|
PtrOwner<ISurfTriMesh> pNewStm( StmFts.GetSurf()) ;
|
|
if ( ! IsNull( pNewStm) && pNewStm->GetTriangleCount() > 0) {
|
|
// la inserisco nel DB
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pNewStm)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nSrfCount ;
|
|
}
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
ExePlaneBoxInters( const Point3d& ptOn, const Vector3d& vtN, const BBox3d& b3Box, int nDestGrpId, int nRefType,
|
|
int* pnPntCount, int* pnCrvCount, int* pnSrfCount)
|
|
{
|
|
// eseguo
|
|
int nPntCount{ 0}, nCrvCount{ 0}, nSrfCount{ 0} ;
|
|
int nFirstId = MyPlaneBoxInters( ptOn, vtN, b3Box, nDestGrpId, nRefType, nPntCount, nCrvCount, nSrfCount) ;
|
|
// aggiorno contatori
|
|
if ( nFirstId != GDB_ID_NULL) {
|
|
if ( pnPntCount != nullptr)
|
|
*pnPntCount = nPntCount ;
|
|
if ( pnCrvCount != nullptr)
|
|
*pnCrvCount = nCrvCount ;
|
|
if ( pnSrfCount != nullptr)
|
|
*pnSrfCount = nSrfCount ;
|
|
ExeSetModified() ;
|
|
}
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtPlaneBoxInters({" + ToString( ptOn) + "},{" +
|
|
ToString( vtN) + "},{" +
|
|
ToString( b3Box) + "}," +
|
|
ToString( nDestGrpId) + "," +
|
|
RefTypeToString( nRefType) + ")" +
|
|
" -- Id1=" + ToString( nFirstId) + ", PntNbr=" + ToString( nPntCount) +
|
|
", CrvNbr=" + ToString( nCrvCount) + ", SrfNbr=" + ToString( nSrfCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static int
|
|
MyPlaneSurfTmInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDestGrpId, int nRefType, double dToler,
|
|
int& nPntCount, int& nCrvCount, int& nSrfCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// recupero il suo riferimento globale
|
|
Frame3d frSurf ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frSurf))
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
// porto in locale il punto e la normale del piano
|
|
Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frSurf) ;
|
|
Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frSurf) ;
|
|
// calcolo il piano di intersezione
|
|
Plane3d plPlane ;
|
|
if ( ! plPlane.Set( ptOnL, vtNL))
|
|
return GDB_ID_NULL ;
|
|
// eseguo l'intersezione
|
|
PNTVECTOR vPnt ;
|
|
BIPNTVECTOR vBpt ;
|
|
TRIA3DVECTOR vTria ;
|
|
if ( ! IntersPlaneSurfTm( plPlane, *pStm, vPnt, vBpt, vTria))
|
|
return GDB_ID_NULL ;
|
|
// inserisco il risultato dell'intersezione nel DB
|
|
int nFirstId = MyAddPlaneIntersResultToGeomDB( pGeomDB, vPnt, vBpt, vTria, frSurf, frDest, nId, nDestGrpId, plPlane.GetVersN(), dToler,
|
|
nPntCount, nCrvCount, nSrfCount) ;
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
ExePlaneSurfTmInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDestGrpId, int nRefType, double dToler,
|
|
int* pnPntCount, int* pnCrvCount, int* pnSrfCount)
|
|
{
|
|
// eseguo
|
|
int nPntCount{ 0}, nCrvCount{ 0}, nSrfCount{ 0} ;
|
|
int nFirstId = MyPlaneSurfTmInters( ptOn, vtN, nId, nDestGrpId, nRefType, dToler, nPntCount, nCrvCount, nSrfCount) ;
|
|
// aggiorno contatori
|
|
if ( nFirstId != GDB_ID_NULL) {
|
|
if ( pnPntCount != nullptr)
|
|
*pnPntCount = nPntCount ;
|
|
if ( pnCrvCount != nullptr)
|
|
*pnCrvCount = nCrvCount ;
|
|
if ( pnSrfCount != nullptr)
|
|
*pnSrfCount = nSrfCount ;
|
|
ExeSetModified() ;
|
|
}
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtPlaneSurfTmInters({" + ToString( ptOn) + "},{" +
|
|
ToString( vtN) + "}," +
|
|
ToString( nId) + "," +
|
|
ToString( nDestGrpId) + "," +
|
|
RefTypeToString( nRefType) + "," +
|
|
ToString( dToler) + ")" +
|
|
" -- Id1=" + ToString( nFirstId) + ", PntNbr=" + ToString( nPntCount) +
|
|
", CrvNbr=" + ToString( nCrvCount) + ", SrfNbr=" + ToString( nSrfCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static int
|
|
MyParPlanesSurfTmInters( const Point3d& ptOn, const Vector3d& vtN, const DBLVECTOR& vdDist, int nId, int nDestGrpId, int nRefType, double dToler, int& nGrpCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero la superficie TriMesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// recupero il suo riferimento globale
|
|
Frame3d frSurf ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frSurf))
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
|
|
// porto in locale la normale del piano
|
|
Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frSurf) ;
|
|
Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frSurf) ;
|
|
// costruisco il frame dei piani
|
|
Frame3d frPlanes ;
|
|
frPlanes.Set( ptOnL, vtNL) ;
|
|
|
|
// intersezione fra superficie e piani paralleli
|
|
IntersParPlanesSurfTm intPlStm( frPlanes, *pStm) ;
|
|
|
|
int nFirstGrpId = GDB_ID_NULL ;
|
|
for ( size_t i = 0 ; i < vdDist.size() ; i++) {
|
|
|
|
// creo il layer in cui salvare
|
|
int nGrpId = pGeomDB->AddGroup( GDB_ID_NULL, nDestGrpId, GLOB_FRM) ;
|
|
nGrpCount ++ ;
|
|
if ( nFirstGrpId == GDB_ID_NULL)
|
|
nFirstGrpId = nGrpId ;
|
|
|
|
// cerco l'intersezione con il piano
|
|
PNTVECTOR vPnt ;
|
|
BIPNTVECTOR vBpt ;
|
|
TRIA3DVECTOR vTria ;
|
|
if ( ! intPlStm.GetInters( vdDist[i], vPnt, vBpt, vTria)) {
|
|
string sErr = "Error on ParPlanesStmInters at distance " + ToString( vdDist[i]) ;
|
|
LOG_ERROR( GetLogger(), sErr.c_str()) ;
|
|
continue ;
|
|
}
|
|
|
|
// inserisco il risultato nel DB
|
|
int nTmp{ 0} ;
|
|
MyAddPlaneIntersResultToGeomDB( pGeomDB, vPnt, vBpt, vTria, frSurf, frDest, nId, nGrpId, vtNL, dToler, nTmp, nTmp, nTmp) ;
|
|
}
|
|
|
|
// restituisco l'identificativo del primo gruppo creato
|
|
return nFirstGrpId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
ExeParPlanesSurfTmInters( const Point3d& ptOn, const Vector3d& vtN, const DBLVECTOR& vdDist, int nId, int nDestGrpId, int nRefType, double dToler,
|
|
int* pnGrpCount)
|
|
{
|
|
// eseguo
|
|
int nGrpCount{ 0} ;
|
|
int nFirstId = MyParPlanesSurfTmInters( ptOn, vtN, vdDist, nId, nDestGrpId, nRefType, dToler, nGrpCount) ;
|
|
// aggiorno contatori
|
|
if ( nFirstId != GDB_ID_NULL) {
|
|
if ( pnGrpCount != nullptr)
|
|
*pnGrpCount = nGrpCount ;
|
|
ExeSetModified() ;
|
|
}
|
|
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtParPlanesSurfTmInters({" + ToString( ptOn) + "},{" +
|
|
ToString( vtN) + "},{" +
|
|
ToString( vdDist) + "}," +
|
|
ToString( nId) + "," +
|
|
ToString( nDestGrpId) + "," +
|
|
RefTypeToString( nRefType) + "," +
|
|
ToString( dToler) + ")" +
|
|
" -- Id=" + ToString( nFirstId) + ", GrpCnt=" + ToString( nGrpCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return nFirstId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
MyPlaneVolZmapInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDestGrpId, int nRefType, int& nCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, false)
|
|
// recupero il riferimento locale
|
|
Frame3d frLoc ;
|
|
if ( ! pGeomDB->GetGlobFrame( nId, frLoc))
|
|
return GDB_ID_NULL ;
|
|
// recupero il riferimento destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
// porto in locale il punto e la normale del piano
|
|
Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frLoc) ;
|
|
Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frLoc) ;
|
|
// calcolo il piano di intersezione
|
|
Plane3d plPlane ;
|
|
if ( ! plPlane.Set( ptOnL, vtNL))
|
|
return GDB_ID_NULL ;
|
|
// recupero lo Zmap e calcolo l'intersezione
|
|
IVolZmap* pVZM = GetVolZmap( pGeomDB->GetGeoObj( nId)) ;
|
|
ICURVEPOVECTOR vpLoop ;
|
|
if ( pVZM == nullptr || ! IntersPlaneVolZmap( plPlane, *pVZM, vpLoop))
|
|
return GDB_ID_NULL ;
|
|
// inserisco le curve nel gruppo destinazione
|
|
int nFirstId = GDB_ID_NULL ;
|
|
for ( size_t i = 0 ; i < vpLoop.size() ; ++ i) {
|
|
PtrOwner<ICurve> pCrv( Release( vpLoop[i])) ;
|
|
if ( IsNull( pCrv))
|
|
continue ;
|
|
pCrv->LocToLoc( frLoc, frDest) ;
|
|
// inserisco la curva composita nel gruppo destinazione
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, ::Release( pCrv)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nCount ;
|
|
}
|
|
// restituisco l'identificativo della prima nuova entità
|
|
return nFirstId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ExePlaneVolZmapInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDestGrpId, int nRefType, int* pnCount)
|
|
{
|
|
// eseguo
|
|
int nCount = 0 ;
|
|
int nFirstId = MyPlaneVolZmapInters( ptOn, vtN, nId, nDestGrpId, nRefType, nCount) ;
|
|
if ( pnCount != nullptr)
|
|
*pnCount = nCount ;
|
|
ExeSetModified() ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtPlaneVolZmapInters({" + ToString( ptOn) + "},{" +
|
|
ToString( vtN) + "}," +
|
|
IdToString( nId) + "," +
|
|
ToString( nDestGrpId) + "," +
|
|
RefTypeToString( nRefType) + ")" +
|
|
" -- Id=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
MyCurveCurveInters( const int nId1, const int nId2, const int nDestGrpId, int& nPntCount, int& nCrvCount, bool bOnly3D)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
|
|
int nFirstId = GDB_ID_NULL ;
|
|
|
|
// recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
|
|
// recupero le curve in locale al gruppo destinazione
|
|
CurveLocal Crv1Loc( pGeomDB, nId1, frDest) ;
|
|
CurveLocal Crv2Loc( pGeomDB, nId2, frDest) ;
|
|
|
|
// intersezione fra le curve nel piano XY locale
|
|
IntersCurveCurve intCC( *Crv1Loc, *Crv2Loc, true) ;
|
|
int nInters = 0 ;
|
|
if ( ! bOnly3D)
|
|
nInters = intCC.GetIntersCount() ;
|
|
else
|
|
nInters = intCC.GetInters3DCount() ;
|
|
|
|
// recupero i punti risultanti
|
|
for ( int i = 0 ; i < nInters ; i++) {
|
|
IntCrvCrvInfo aInfo ;
|
|
if( ! bOnly3D)
|
|
intCC.GetIntCrvCrvInfo( i, aInfo) ;
|
|
else
|
|
intCC.GetInt3DCrvCrvInfo( i, aInfo) ;
|
|
// verifico se punto
|
|
if ( ! aInfo.bOverlap) {
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
if ( IsNull( pGeoPnt))
|
|
return GDB_ID_NULL ;
|
|
pGeoPnt->Set( aInfo.IciA[0].ptI) ;
|
|
// lo inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// aggiorno parametri
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nPntCount ;
|
|
}
|
|
}
|
|
|
|
// recupero le curve risultanti
|
|
for ( int i = 0 ; i < nInters ; i++) {
|
|
IntCrvCrvInfo aInfo ;
|
|
if( ! bOnly3D)
|
|
intCC.GetIntCrvCrvInfo( i, aInfo) ;
|
|
else
|
|
intCC.GetInt3DCrvCrvInfo( i, aInfo) ;
|
|
// verifico se curva
|
|
if ( aInfo.bOverlap) {
|
|
PtrOwner<ICurve> pCrvRes( Crv1Loc->CopyParamRange( aInfo.IciA[0].dU, aInfo.IciA[1].dU)) ;
|
|
if ( IsNull( pCrvRes))
|
|
return GDB_ID_NULL ;
|
|
// lo inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvRes)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// aggiorno parametri
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nCrvCount ;
|
|
}
|
|
}
|
|
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
ExeCurveCurveInters( const int nId1, const int nId2, const int nDestGrpId, int* pnPntCount, int* pnCrvCount, bool bOnly3D)
|
|
{
|
|
// eseguo
|
|
int nPntCount{ 0}, nCrvCount{ 0} ;
|
|
int nFirstId = MyCurveCurveInters( nId1, nId2, nDestGrpId, nPntCount, nCrvCount, bOnly3D) ;
|
|
// aggiorno contatori
|
|
if ( nFirstId != GDB_ID_NULL) {
|
|
if ( pnPntCount != nullptr)
|
|
*pnPntCount = nPntCount ;
|
|
if ( pnCrvCount != nullptr)
|
|
*pnCrvCount = nCrvCount ;
|
|
ExeSetModified() ;
|
|
}
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtCurveCurveInters(" + ToString( nId1) + "," +
|
|
ToString( nId2) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id=" + ToString( nFirstId) + ", nPntCnt=" + ToString( nPntCount) + ", nCrvCnt=" + ToString( nCrvCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static string
|
|
GetCurveSurfTmIntersType( int nFlag)
|
|
{
|
|
switch ( nFlag) {
|
|
case CSIT_OUT_IN : return "OUT->IN" ;
|
|
case CSIT_IN_OUT : return "IN->OUT" ;
|
|
case CSIT_IN_IN : return "IN->IN" ;
|
|
case CSIT_OUT_OUT : return "OUT->OUT" ;
|
|
case CSIT_IN_ON : return "IN->ON" ;
|
|
case CSIT_ON_IN : return "ON->IN" ;
|
|
case CSIT_OUT_ON : return "OUT->ON" ;
|
|
case CSIT_ON_OUT : return "ON->OUT" ;
|
|
}
|
|
return "NONE" ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static int
|
|
MyCurveSurfTmInters( const int nCrvId, const int nId2, const int nDestGrpId, int& nPntCount, int& nCrvCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
|
|
int nFirstId = GDB_ID_NULL ;
|
|
|
|
// recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
|
|
// recupero la curva e la superficie in locale al gruppo destinazione
|
|
CurveLocal CrvLoc( pGeomDB, nCrvId, frDest) ;
|
|
const ICurve* pCrv = GetCurve( CrvLoc) ;
|
|
if ( pCrv == nullptr)
|
|
return GDB_ID_NULL ;
|
|
SurfLocal StmLoc( pGeomDB, nId2, frDest) ;
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( StmLoc) ;
|
|
if ( pStm == nullptr)
|
|
return GDB_ID_NULL ;
|
|
|
|
// intersezione filtrata tra la curva e la superficie locali
|
|
INTDBLVECTOR vInters ;
|
|
if ( ! IntersCurveSurfTmExt( *pCrv, *pStm, 10 * EPS_SMALL, vInters))
|
|
return GDB_ID_NULL ;
|
|
|
|
// recupero i punti e le curve risultanti
|
|
for ( int i = 0 ; i < int( vInters.size()) ; i++) {
|
|
// verifico se punto
|
|
if ( vInters[i].first == CSIT_OUT_IN || vInters[i].first == CSIT_IN_OUT ||
|
|
vInters[i].first == CSIT_IN_IN || vInters[i].first == CSIT_OUT_OUT || vInters[i].first == CSIT_NONE) {
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
if ( IsNull( pGeoPnt))
|
|
return GDB_ID_NULL ;
|
|
Point3d ptP ;
|
|
pCrv->GetPointD1D2( vInters[i].second, ICurve::FROM_MINUS, ptP) ;
|
|
pGeoPnt->Set( ptP) ;
|
|
// lo inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// aggiorno parametri
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nPntCount ;
|
|
// assegno info di tipo
|
|
pGeomDB->SetInfo( nNewId, "CSI", GetCurveSurfTmIntersType( vInters[i].first) +
|
|
" (" + ToString( vInters[i].second) + ")") ;
|
|
}
|
|
// altrimenti dovrebbe essere sovrapposizione
|
|
else {
|
|
// indice di inizio
|
|
int h = ( i > 0 ? i - 1 : int( vInters.size()) - 1) ;
|
|
// verifico se sovrapposizione
|
|
if ( ( vInters[h].first == CSIT_IN_ON || vInters[h].first == CSIT_OUT_ON) &&
|
|
( vInters[i].first == CSIT_ON_IN || vInters[i].first == CSIT_ON_OUT)) {
|
|
PtrOwner<ICurve> pCrvRes( pCrv->CopyParamRange( vInters[h].second, vInters[i].second)) ;
|
|
if ( IsNull( pCrvRes))
|
|
return GDB_ID_NULL ;
|
|
// lo inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvRes)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// aggiorno parametri
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nCrvCount ;
|
|
// assegno info di tipo
|
|
pGeomDB->SetInfo( nNewId, "CSI_INI", GetCurveSurfTmIntersType( vInters[h].first) +
|
|
" (" + ToString( vInters[h].second) + ")") ;
|
|
pGeomDB->SetInfo( nNewId, "CSI_FIN", GetCurveSurfTmIntersType( vInters[i].first) +
|
|
" (" + ToString( vInters[i].second) + ")") ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
ExeCurveSurfTmInters( const int nCrvId, const int nStmId, const int nDestGrpId, int* pnPntCount, int* pnCrvCount)
|
|
{
|
|
// eseguo
|
|
int nPntCount{ 0}, nCrvCount{ 0} ;
|
|
int nFirstId = MyCurveSurfTmInters( nCrvId, nStmId, nDestGrpId, nPntCount, nCrvCount) ;
|
|
// aggiorno contatori
|
|
if ( nFirstId != GDB_ID_NULL) {
|
|
if ( pnPntCount != nullptr)
|
|
*pnPntCount = nPntCount ;
|
|
if ( pnCrvCount != nullptr)
|
|
*pnCrvCount = nCrvCount ;
|
|
ExeSetModified() ;
|
|
}
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtCurveSurfTmInters(" + ToString( nCrvId) + "," +
|
|
ToString( nStmId) + "," +
|
|
ToString( nDestGrpId) + ")" +
|
|
" -- Id=" + ToString( nFirstId) + ", nPntCnt=" + ToString( nPntCount) + ", nCrvCnt=" + ToString( nCrvCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static bool
|
|
MyChainCurvesForSurfSurfInters( const BIPNTVECTOR& vBpt, IGeomDB* pGeomDB, int nDestGrpId, int nId1, double dToler,
|
|
int& nFirstId, int& nCrvCount)
|
|
{
|
|
// Concateno i tratti di curva
|
|
ChainCurves chainC ;
|
|
chainC.Init( false, dToler, int( vBpt.size())) ;
|
|
for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) {
|
|
Vector3d vtDir = vBpt[i].second - vBpt[i].first ;
|
|
vtDir.Normalize() ;
|
|
if ( ! chainC.AddCurve( i + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir))
|
|
return false ;
|
|
}
|
|
// recupero i percorsi concatenati
|
|
ICRVCOMPOPOVECTOR vCrvCompo ;
|
|
Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ;
|
|
INTVECTOR vId ;
|
|
while ( chainC.GetChainFromNear( ptNear, true, vId)) {
|
|
// creo una curva composita
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvCompo))
|
|
return false ;
|
|
// recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita
|
|
bool bAdded = true ;
|
|
for ( int i = 0 ; i < int( vId.size()) ; ++ i) {
|
|
// creo un segmento di retta
|
|
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
|
|
if ( IsNull( pLine))
|
|
return GDB_ID_NULL ;
|
|
// recupero gli estremi (non vanno mai invertiti per opzione di concatenamento)
|
|
int nInd = abs( vId[i]) - 1 ;
|
|
Point3d ptStart = ( bAdded ? vBpt[nInd].first : ptNear) ;
|
|
Point3d ptEnd = vBpt[nInd].second ;
|
|
// provo ad accodarlo alla composita
|
|
bAdded = ( Dist( ptStart, ptEnd) > dToler / 2 &&
|
|
pLine->Set( ptStart, ptEnd) &&
|
|
pCrvCompo->AddCurve( Release( pLine), true, dToler)) ;
|
|
ptNear = ( bAdded ? ptEnd : ptStart) ;
|
|
}
|
|
// se lunghezza curva inferiore a 5 volte la tolleranza, la salto
|
|
double dCrvLen ;
|
|
if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5 * dToler)
|
|
continue ;
|
|
// unisco segmenti allineati
|
|
pCrvCompo->MergeCurves( dToler, ANG_TOL_STD_DEG) ;
|
|
// la salvo
|
|
vCrvCompo.emplace_back( Release( pCrvCompo)) ;
|
|
}
|
|
// Ripeto concatenamento sulle curve appena create (per riempire eventuali mini buchi)
|
|
chainC.Init( false, dToler, int( vCrvCompo.size())) ;
|
|
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) {
|
|
Point3d ptStart ; vCrvCompo[i]->GetStartPoint( ptStart) ;
|
|
Vector3d vtStart ; vCrvCompo[i]->GetStartDir( vtStart) ;
|
|
Point3d ptEnd ; vCrvCompo[i]->GetEndPoint( ptEnd) ;
|
|
Vector3d vtEnd ; vCrvCompo[i]->GetEndDir( vtEnd) ;
|
|
if ( ! chainC.AddCurve( i + 1, ptStart, vtStart, ptEnd, vtEnd))
|
|
return false ;
|
|
}
|
|
// recupero i percorsi concatenati
|
|
if ( ! vCrvCompo.empty())
|
|
vCrvCompo[0]->GetStartPoint( ptNear) ;
|
|
else
|
|
ptNear = ORIG ;
|
|
while ( chainC.GetChainFromNear( ptNear, true, vId)) {
|
|
// creo una curva composita
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvCompo))
|
|
return false ;
|
|
// inserisco le curve nella composita
|
|
for ( int i = 0 ; i < int( vId.size()) ; ++ i) {
|
|
// recupero dati
|
|
int nInd = abs( vId[i]) - 1 ;
|
|
bool bInvert = ( vId[i] < 0) ;
|
|
if ( bInvert)
|
|
vCrvCompo[nInd]->Invert() ;
|
|
// accodo
|
|
if ( ! pCrvCompo->AddCurve( Release( vCrvCompo[nInd]), true, 1.1 * dToler))
|
|
return false ;
|
|
// aggiorno il prossimo near
|
|
pCrvCompo->GetEndPoint( ptNear) ;
|
|
}
|
|
// se curva chiusa entro 5 volte la tolleranza ma considerata aperta, la chiudo bene
|
|
Point3d ptStart, ptEnd ;
|
|
if ( pCrvCompo->GetStartPoint( ptStart) &&
|
|
pCrvCompo->GetEndPoint( ptEnd) &&
|
|
AreSamePointEpsilon( ptStart, ptEnd, 5 * dToler) &&
|
|
! AreSamePointApprox( ptStart, ptEnd)) {
|
|
// porto il punto finale a coincidere esattamente con l'inizio
|
|
pCrvCompo->ModifyEnd( ptStart) ;
|
|
}
|
|
// unisco segmenti allineati
|
|
pCrvCompo->MergeCurves( dToler, ANG_TOL_STD_DEG) ;
|
|
// la inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return false ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId1, nNewId))
|
|
return false ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nCrvCount ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
static int
|
|
MySurfTmSurfTmInters( int nId1, int nId2, int nDestGrpId, double dToler,
|
|
int& nPntCount, int& nCrvCount, int& nSrfCount)
|
|
{
|
|
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
|
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
|
|
// recupero il riferimento del gruppo di destinazione
|
|
Frame3d frDest ;
|
|
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
|
|
return GDB_ID_NULL ;
|
|
// recupero la prima superficie TriMesh espressa nel riferimento destinazione
|
|
SurfLocal Surf1Loc( pGeomDB, nId1, frDest) ;
|
|
const ISurfTriMesh* pStm1L = GetSurfTriMesh( Surf1Loc) ;
|
|
if ( pStm1L == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// recupero la seconda superficie TriMesh espressa nel riferimento destinazione
|
|
SurfLocal Surf2Loc( pGeomDB, nId2, frDest) ;
|
|
const ISurfTriMesh* pStm2L = GetSurfTriMesh( Surf2Loc) ;
|
|
if ( pStm2L == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// eseguo l'intersezione (gi� espressa nel riferimento destinazione)
|
|
PNTVECTOR vPnt ;
|
|
BIPNTVECTOR vBpt ;
|
|
TRIA3DVECTOR vTria ;
|
|
if ( ! IntersSurfTmSurfTm( *pStm1L, *pStm2L, vPnt, vBpt, vTria))
|
|
return GDB_ID_NULL ;
|
|
// Inserisco il risultato nel DB
|
|
int nFirstId = GDB_ID_NULL ;
|
|
// Inserisco i punti nel DB
|
|
for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) {
|
|
// creo il punto
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
if ( IsNull( pGeoPnt))
|
|
return GDB_ID_NULL ;
|
|
// setto il punto
|
|
pGeoPnt->Set( vPnt[i]) ;
|
|
// lo inserisco nel DB geometrico
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId1, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nPntCount ;
|
|
}
|
|
// Inserisco le curve nel DB (dopo averle concatenate)
|
|
if ( ! MyChainCurvesForSurfSurfInters( vBpt, pGeomDB, nDestGrpId, nId1, dToler, nFirstId, nCrvCount))
|
|
return GDB_ID_NULL ;
|
|
// Inserisco i triangoli nel DB (dopo averli uniti in una superficie trimesh)
|
|
StmFromTriangleSoup StmFts ;
|
|
if ( ! StmFts.Start())
|
|
return GDB_ID_NULL ;
|
|
for ( int i = 0 ; i < int( vTria.size()) ; ++ i)
|
|
// inserisco il triangolo nella nuova superficie
|
|
StmFts.AddTriangle( vTria[i]) ;
|
|
// valido la superficie e calcolo le adiacenze
|
|
if ( ! StmFts.End())
|
|
return GDB_ID_NULL ;
|
|
// se superficie con triangoli
|
|
PtrOwner<ISurfTriMesh> pNewStm( StmFts.GetSurf()) ;
|
|
if ( ! IsNull( pNewStm) && pNewStm->GetTriangleCount() > 0) {
|
|
// la inserisco nel DB
|
|
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pNewStm)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// copio il materiale
|
|
if ( ! pGeomDB->CopyMaterial( nId1, nNewId))
|
|
return GDB_ID_NULL ;
|
|
// aggiorno contatori
|
|
if ( nFirstId == GDB_ID_NULL)
|
|
nFirstId = nNewId ;
|
|
++ nSrfCount ;
|
|
}
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
int
|
|
ExeSurfTmSurfTmInters( int nId1, int nId2, int nDestGrpId, double dToler,
|
|
int* pnPntCount, int* pnCrvCount, int* pnSrfCount)
|
|
{
|
|
// eseguo
|
|
int nPntCount{ 0}, nCrvCount{ 0}, nSrfCount{ 0} ;
|
|
int nFirstId = MySurfTmSurfTmInters( nId1, nId2, nDestGrpId, dToler, nPntCount, nCrvCount, nSrfCount) ;
|
|
// aggiorno contatori
|
|
if ( nFirstId != GDB_ID_NULL) {
|
|
if ( pnPntCount != nullptr)
|
|
*pnPntCount = nPntCount ;
|
|
if ( pnCrvCount != nullptr)
|
|
*pnCrvCount = nCrvCount ;
|
|
if ( pnSrfCount != nullptr)
|
|
*pnSrfCount = nSrfCount ;
|
|
ExeSetModified() ;
|
|
}
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "EgtSurfTmSurfTmInters(" + ToString( nId1) + "," +
|
|
ToString( nId2) + "," +
|
|
ToString( nDestGrpId) + "," +
|
|
ToString( dToler) + ")" +
|
|
" -- Id1=" + ToString( nFirstId) + ", PntNbr=" + ToString( nPntCount) +
|
|
", CrvNbr=" + ToString( nCrvCount) + ", SrfNbr=" + ToString( nSrfCount) ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco l'identificativo della prima nuova entit�
|
|
return nFirstId ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
bool
|
|
ExeBBoxOverlap( const BBox3d& bboxA, const Frame3d& frA, const BBox3d& bboxB, const Frame3d& frB)
|
|
{
|
|
bool bRes = Overlaps( bboxA, frA, bboxB, frB) ;
|
|
// se richiesto, salvo il comando Lua equivalente
|
|
if ( IsCmdLog()) {
|
|
string sLua = "ExeBBoxOverlap(" + ToString( bboxA) + "," +
|
|
ToString( frA) + "," +
|
|
ToString( bboxB) + "," +
|
|
ToString( frB) + ")" ;
|
|
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
|
|
}
|
|
// restituisco il risultato
|
|
return bRes ;
|
|
} |