Files
EgtExecutor/EXE_GeoSnap.cpp
T
Dario Sassi 0124dd8c3b EgtExecutor 2.1k2 :
- corretta funzione Exe e Lua SurfTmFacetMinAreaRectangle che non impostava correttamente il riferimento restituito del rettangolo minimo.
2019-11-14 19:43:40 +00:00

1584 lines
54 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2014-2015
//----------------------------------------------------------------------------
// File : EXE_GeoSnap.cpp Data : 05.05.15 Versione : 1.6e1
// Contenuto : Funzioni di snap ad oggetti del DB geometrico per EXE.
//
//
//
// Modifiche : 02.10.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "EXE.h"
#include "EXE_Const.h"
#include "EXE_Macro.h"
#include "GeoTools.h"
#include "/EgtDev/Include/EXeExecutor.h"
#include "/EgtDev/Include/EXeConst.h"
#include "/EgtDev/Include/EGkGeoPoint3d.h"
#include "/EgtDev/Include/EGkGeoVector3d.h"
#include "/EgtDev/Include/EGkCurve.h"
#include "/EgtDev/Include/EGkCurveArc.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
#include "/EgtDev/Include/EGkCurveLocal.h"
#include "/EgtDev/Include/EGkSurf.h"
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EGkSurfLocal.h"
#include "/EgtDev/Include/EGkVolZmap.h"
#include "/EgtDev/Include/EGkExtText.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
#include "/EgtDev/Include/EGkIntersCurves.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include <string>
using namespace std ;
//----------------------------------------------------------------------------
bool
ExeStartPoint( int nId, int nRefId, Point3d& ptP)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se non è entità geometrica
const IGeoObj* pGObj ;
if ( ( pGObj = pGeomDB->GetGeoObj( nId)) == nullptr)
return false ;
// se punto
if ( pGObj->GetType() == GEO_PNT3D) {
// recupero il geo-punto
const IGeoPoint3d* pGP = GetGeoPoint3d( pGObj) ;
// assegno il punto
ptP = pGP->GetPoint() ;
}
// se vettore
else if ( pGObj->GetType() == GEO_VECT3D) {
// recupero il geo-vettore
const IGeoVector3d* pGV = GetGeoVector3d( pGObj) ;
// assegno il punto
ptP = pGV->GetBase() ;
}
// se frame
else if ( pGObj->GetType() == GEO_FRAME3D) {
// recupero il frame
const IGeoFrame3d* pGF = GetGeoFrame3d( pGObj) ;
// assegno il punto
ptP = pGF->GetFrame().Orig() ;
}
// se curva
else if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv = GetCurve( pGObj) ;
// assegno il punto
if ( pCrv == nullptr || ! pCrv->GetStartPoint( ptP))
return false ;
}
// se testo
else if ( pGObj->GetType() == EXT_TEXT) {
// recupero il testo
const IExtText* pTxt = GetExtText( pGObj) ;
// assegno il punto
if ( pTxt == nullptr || ! pTxt->GetStartPoint( ptP))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformPoint( pGeomDB, nId, nRefId, ptP) ;
}
//----------------------------------------------------------------------------
bool
ExeEndPoint( int nId, int nRefId, Point3d& ptP)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se non è entità geometrica
const IGeoObj* pGObj ;
if ( ( pGObj = pGeomDB->GetGeoObj( nId)) == nullptr)
return false ;
// se vettore
if ( pGObj->GetType() == GEO_VECT3D) {
// recupero il geo-vettore
const IGeoVector3d* pGV = GetGeoVector3d( pGObj) ;
// assegno il punto
ptP = pGV->GetBase() + pGV->GetVector() ;
}
// se curva
else if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv = GetCurve( pGObj) ;
if ( pCrv == nullptr || ! pCrv->GetEndPoint( ptP))
return false ;
}
// se testo
else if ( pGObj->GetType() == EXT_TEXT) {
// recupero il testo
const IExtText* pTxt = GetExtText( pGObj) ;
if ( pTxt == nullptr || ! pTxt->GetEndPoint( ptP))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformPoint( pGeomDB, nId, nRefId, ptP) ;
}
//----------------------------------------------------------------------------
bool
ExeMidPoint( int nId, int nRefId, Point3d& ptP)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se non è entità geometrica
const IGeoObj* pGObj ;
if ( ( pGObj = pGeomDB->GetGeoObj( nId)) == nullptr)
return false ;
// se curva
if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv = GetCurve( pGObj) ;
// assegno il punto
if ( pCrv == nullptr || ! pCrv->GetMidPoint( ptP))
return false ;
}
// se testo
else if ( pGObj->GetType() == EXT_TEXT) {
// recupero il testo
const IExtText* pTxt = GetExtText( pGObj) ;
// assegno il punto
if ( pTxt == nullptr || ! pTxt->GetMidPoint( ptP))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformPoint( pGeomDB, nId, nRefId, ptP) ;
}
//----------------------------------------------------------------------------
bool
ExeCenterPoint( int nId, int nRefId, Point3d& ptP)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se non è entità geometrica
const IGeoObj* pGObj ;
if ( ( pGObj = pGeomDB->GetGeoObj( nId)) == nullptr)
return false ;
// se curva
if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv = GetCurve( pGObj) ;
// assegno il punto
if ( pCrv == nullptr || ! pCrv->GetCenterPoint( ptP))
return false ;
}
// se superficie regione piana
else if ( pGObj->GetType() == SRF_FLATRGN) {
// recupero la regione
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGObj) ;
// assegno il punto
if ( pSfr == nullptr || ! pSfr->GetCentroid( ptP))
return false ;
}
// se testo
else if ( pGObj->GetType() == EXT_TEXT) {
// recupero il testo
const IExtText* pTxt = GetExtText( pGObj) ;
// assegno il punto
if ( pTxt == nullptr || ! pTxt->GetCenterPoint( ptP))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformPoint( pGeomDB, nId, nRefId, ptP) ;
}
//----------------------------------------------------------------------------
bool
ExeCentroid( int nId, int nRefId, Point3d& ptP)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se non è entità geometrica
const IGeoObj* pGObj ;
if ( ( pGObj = pGeomDB->GetGeoObj( nId)) == nullptr)
return false ;
// se curva
if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv = GetCurve( pGObj) ;
// assegno il punto
if ( pCrv == nullptr || ! pCrv->GetCentroid( ptP))
return false ;
}
// se superficie
else if ( ( pGObj->GetType() & GEO_SURF) != 0) {
// recupero la superficie
const ISurf* pSrf = GetSurf( pGObj) ;
// assegno il punto
if ( pSrf == nullptr || ! pSrf->GetCentroid( ptP))
return false ;
}
// se testo
else if ( pGObj->GetType() == EXT_TEXT) {
// recupero il testo
const IExtText* pTxt = GetExtText( pGObj) ;
// assegno il punto
if ( pTxt == nullptr || ! pTxt->GetCenterPoint( ptP))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformPoint( pGeomDB, nId, nRefId, ptP) ;
}
//----------------------------------------------------------------------------
bool
ExeAtParamPoint( int nId, double dU, int nRefId, Point3d& ptP)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se non è entità geometrica
const IGeoObj* pGObj ;
if ( ( pGObj = pGeomDB->GetGeoObj( nId)) == nullptr)
return false ;
// se curva
if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv = GetCurve( pGObj) ;
if ( pCrv == nullptr || ! pCrv->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformPoint( pGeomDB, nId, nRefId, ptP) ;
}
//----------------------------------------------------------------------------
bool
ExeNearPoint( int nId, const Point3d& ptNear, int nRefId, Point3d& ptP)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se non è entità geometrica
const IGeoObj* pGObj = pGeomDB->GetGeoObj( nId) ;
if ( pGObj == nullptr)
return false ;
// porto il punto near nel riferimento dell'entità
Point3d ptNearL = ptNear ;
if ( ! InvTransformPoint( pGeomDB, nId, nRefId, ptNearL))
return false ;
// se curva
if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv = GetCurve( pGObj) ;
// calcolo il punto della curva più vicino al punto di riferimento
DistPointCurve dstPC( ptNearL, *pCrv) ;
int nFlag ;
if ( ! dstPC.GetMinDistPoint( 0, ptP, nFlag))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformPoint( pGeomDB, nId, nRefId, ptP) ;
}
//----------------------------------------------------------------------------
bool
ExeIntersectionPoint( int nId1, int nId2, const Point3d& ptNear, int nRefId, Point3d& ptP)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se auto-intersezione
if ( nId1 == nId2) {
// deve essere entità geometriche
const IGeoObj* pGObj1 ;
if ( ( pGObj1 = pGeomDB->GetGeoObj( nId1)) == nullptr)
return false ;
// se curva
if ( ( pGObj1->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv1 = GetCurve( pGObj1) ;
// porto il punto Near nel riferimento dell'entità
Point3d ptNearL = ptNear ;
if ( ! InvTransformPoint( pGeomDB, nId1, nRefId, ptNearL))
return false ;
// calcolo il punto di auto-intersezione sulla curva più vicino al punto di riferimento
SelfIntersCurve sintC( *pCrv1) ;
if ( ! sintC.GetIntersPointNearTo( ptNearL, ptP))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformPoint( pGeomDB, nId1, nRefId, ptP) ;
}
// devono essere entità geometriche
const IGeoObj* pGObj1 ;
if ( ( pGObj1 = pGeomDB->GetGeoObj( nId1)) == nullptr)
return false ;
const IGeoObj* pGObj2 ;
if ( ( pGObj2 = pGeomDB->GetGeoObj( nId2)) == nullptr)
return false ;
// se curve
if ( ( pGObj1->GetType() & GEO_CURVE) != 0 && ( pGObj2->GetType() & GEO_CURVE) != 0) {
// recupero le curve
const ICurve* pCrv1 = GetCurve( pGObj1) ;
const ICurve* pCrv2 = GetCurve( pGObj2) ;
// recupero i riferimenti in cui sono immerse
Frame3d frEnt1 ;
if ( ! pGeomDB->GetGlobFrame( nId1, frEnt1))
return false ;
Frame3d frEnt2 ;
if ( ! pGeomDB->GetGlobFrame( nId2, frEnt2))
return false ;
// se il riferimento della seconda curva è diverso da quello della prima entità, devo trasformarla
PtrOwner<ICurve> pcrvTrans ;
if ( ! AreSameFrame( frEnt1, frEnt2)) {
pcrvTrans.Set( pCrv2->Clone()) ;
if ( IsNull( pcrvTrans))
return false ;
pcrvTrans->LocToLoc( frEnt2, frEnt1) ;
pCrv2 = pcrvTrans ;
}
// porto il punto Near nel riferimento della prima entità
Point3d ptNearL = ptNear ;
if ( ! InvTransformPoint( pGeomDB, nId1, nRefId, ptNearL))
return false ;
// calcolo il punto di intersezione sulla prima curva più vicino al punto di riferimento
IntersCurveCurve intCC( *pCrv1, *pCrv2, true) ;
if ( ! intCC.GetIntersPointNearTo( 0, ptNearL, ptP))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformPoint( pGeomDB, nId1, nRefId, ptP) ;
}
//----------------------------------------------------------------------------
bool
ExeStartVector( int nId, int nRefId, Vector3d& vtV)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se non è entità geometrica
const IGeoObj* pGObj = pGeomDB->GetGeoObj( nId) ;
if ( pGObj == nullptr)
return false ;
// se vettore
if ( pGObj->GetType() == GEO_VECT3D) {
// recupero il geo-vettore
const IGeoVector3d* pGV = GetGeoVector3d( pGObj) ;
// assegno il vettore
vtV = pGV->GetVector() ;
}
// se curva
else if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv = GetCurve( pGObj) ;
// assegno il vettore
if ( ! pCrv->GetStartDir( vtV))
return false ;
}
// se testo
else if ( pGObj->GetType() == EXT_TEXT) {
// recupero il testo
const IExtText* pTxt = GetExtText( pGObj) ;
// assegno il vettore
vtV = pTxt->GetDirVersor() ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformVector( pGeomDB, nId, nRefId, vtV) ;
}
//----------------------------------------------------------------------------
bool
ExeEndVector( int nId, int nRefId, Vector3d& vtV)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se non è entità geometrica
const IGeoObj* pGObj = pGeomDB->GetGeoObj( nId) ;
if ( pGObj == nullptr)
return false ;
// se curva
if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv = GetCurve( pGObj) ;
// assegno il vettore
if ( ! pCrv->GetEndDir( vtV))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformVector( pGeomDB, nId, nRefId, vtV) ;
}
//----------------------------------------------------------------------------
bool
ExeMidVector( int nId, int nRefId, Vector3d& vtV)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se non è entità geometrica
const IGeoObj* pGObj ;
if ( ( pGObj = pGeomDB->GetGeoObj( nId)) == nullptr)
return false ;
// se curva
if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv = GetCurve( pGObj) ;
// assegno il vettore
if ( ! pCrv->GetMidDir( vtV))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformVector( pGeomDB, nId, nRefId, vtV) ;
}
//----------------------------------------------------------------------------
bool
ExeAtParamVector( int nId, double dU, int nSide, int nRefId, Vector3d& vtV)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se non è entità geometrica
const IGeoObj* pGObj ;
if ( ( pGObj = pGeomDB->GetGeoObj( nId)) == nullptr)
return false ;
// se curva
if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
// recupero la curva
const ICurve* pCrv = GetCurve( pGObj) ;
// assegno il lato di approccio
ICurve::Side nSide = ICurve::FROM_MINUS ;
if ( nSide > 0)
nSide = ICurve::FROM_PLUS ;
// recupero la direzione
Point3d ptP ;
if ( ! pCrv->GetPointTang( dU, nSide, ptP, vtV))
return false ;
}
else
return false ;
// gestione trasformazione ( eventuale)
return TransformVector( pGeomDB, nId, nRefId, vtV) ;
}
//----------------------------------------------------------------------------
bool
ExeFrame( int nId, int nRefId, Frame3d& frFrame)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se gruppo
if ( pGeomDB->GetGroupFrame( nId, frFrame))
// gestione trasformazione ( eventuale)
return TransformFrame( pGeomDB, nId, nRefId, frFrame) ;
// se geo frame
const IGeoObj* pGObj ;
if ( ( pGObj = pGeomDB->GetGeoObj( nId)) != nullptr &&
pGObj->GetType() == GEO_FRAME3D) {
frFrame = GetGeoFrame3d( pGObj)->GetFrame() ;
// gestione trasformazione ( eventuale)
return TransformFrame( pGeomDB, nId, nRefId, frFrame) ;
}
// errore
return false ;
}
//----------------------------------------------------------------------------
bool
ExeCurveDomain( int nId, double* pdStart, double* pdEnd)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico i parametri
if ( pdStart == nullptr || pdEnd == nullptr)
return false ;
// recupero la curva
ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
// recupero il dominio
return ( pCurve != nullptr && pCurve->GetDomain( *pdStart, *pdEnd)) ;
}
//----------------------------------------------------------------------------
bool
ExeCurveLength( int nId, double* pdLen)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( pdLen == nullptr)
return false ;
// recupero la curva
ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
// recupero la lunghezza
return ( pCurve != nullptr && pCurve->GetLength( *pdLen)) ;
}
//----------------------------------------------------------------------------
bool
ExeCurveLengthAtPoint( int nId, const Point3d& ptOn, double dExtend, double* pdLen)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( pdLen == nullptr)
return false ;
// recupero la curva
const ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
if ( pCurve == nullptr)
return false ;
// determino la posizione parametrica del punto sulla curva (con tolleranza)
int nFlag ;
double dU ;
if ( ! DistPointCurve( ptOn, *pCurve).GetParamAtMinDistPoint( 0, dU, nFlag) || nFlag != MDPCI_NORMAL)
return false ;
// se non richiesta estensione o punto interno alla curva, recupero la lunghezza alla posizione parametrica
if ( dExtend < EPS_SMALL ||
( ! pCurve->IsStartParam( dU) && ! pCurve->IsEndParam( dU)))
return ( pCurve->GetLengthAtParam( dU, *pdLen) ? true : false) ;
// allungo la curva dalla parte del punto
PtrOwner<ICurve> pCopy( pCurve->Clone()) ;
if ( IsNull( pCopy))
return false ;
double dDeltaIni ;
if ( pCopy->IsStartParam( dU)) {
pCopy->ExtendStartByLen( dExtend) ;
dDeltaIni = dExtend ;
}
else {
pCopy->ExtendEndByLen( dExtend) ;
dDeltaIni = 0 ;
}
if ( ! DistPointCurve( ptOn, *pCopy).GetParamAtMinDistPoint( 0, dU, nFlag) || nFlag != MDPCI_NORMAL)
return false ;
if ( pCopy->GetLengthAtParam( dU, *pdLen)) {
*pdLen -= dDeltaIni ;
return true ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
ExeCurveIsClosed( int nId)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la curva
ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
// verifico se chiusa
return ( pCurve != nullptr && pCurve->IsClosed()) ;
}
//----------------------------------------------------------------------------
bool
ExeCurveIsFlat( int nId, Plane3d& Plane, double dToler)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( &Plane == nullptr)
return false ;
// recupero la curva
ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
// ne verifico la planarità
return ( pCurve != nullptr && pCurve->IsFlat( Plane, dToler)) ;
}
//----------------------------------------------------------------------------
bool
ExeCurveAreaXY( int nId, double& dArea)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( &dArea == nullptr)
return false ;
// recupero la curva
ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
// determino l'area nel piano XY
return ( pCurve != nullptr && pCurve->GetAreaXY( dArea)) ;
}
//----------------------------------------------------------------------------
bool
ExeCurveArea( int nId, Plane3d& Plane, double& dArea)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico i parametri
if ( &Plane == nullptr || &dArea == nullptr)
return false ;
// recupero la curva
ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
// determino il piano medio della curva e la sua area su di esso (deve essere chiusa)
return ( pCurve != nullptr && pCurve->GetArea( Plane, dArea)) ;
}
//----------------------------------------------------------------------------
bool
ExeCurveNearestExtremityToPoint( int nId, const Point3d& ptP, bool& bStart)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la curva
ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
// recupero quale estremo è più vicino al punto
return ( pCurve != nullptr && pCurve->GetNearestExtremityToPoint( ptP, bStart)) ;
}
//----------------------------------------------------------------------------
bool
ExeCurveExtrusion( int nId, int nRefId, Vector3d& vtExtr)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la curva
ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
// ne ricavo il vettore estrusione
if ( pCurve == nullptr || ! pCurve->GetExtrusion( vtExtr))
return false ;
// gestione trasformazione ( eventuale)
return TransformVector( pGeomDB, nId, nRefId, vtExtr) ;
}
//----------------------------------------------------------------------------
bool
ExeCurveThickness( int nId, double* pdThick)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( pdThick == nullptr)
return false ;
// recupero la curva
ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
// recupero lo spessore
return ( pCurve != nullptr && pCurve->GetThickness( *pdThick)) ;
}
//----------------------------------------------------------------------------
bool
ExeCurveSelfIntersCount( int nId, int* pnCount)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( pnCount == nullptr)
return false ;
// recupero la curva
ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
if ( pCurve == nullptr)
return false ;
// calcolo le auto-intersezioni
SelfIntersCurve sintC( *pCurve) ;
// ne recupero il numero
*pnCount = sintC.GetIntersCount() ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExeCurveMinAreaRectangleXY( int nId, int nRefId, Frame3d& frRect, double& dDimX, double& dDimY)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la curva
ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ;
bool bOk = ( pCurve != nullptr) ;
// recupero il riferimento della curva
Frame3d frCrv ;
bOk = bOk && pGeomDB->GetGlobFrame( nId, frCrv) ;
// derivo la polilinea di approssimazione della curva entro la tolleranza standard
PolyLine PL ;
bOk = bOk && pCurve->ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, APP_LINES, PL) ;
// eventuale trasformazione per riferimento di espressione
if ( bOk && nRefId == GDB_ID_ROOT)
PL.ToGlob( frCrv) ;
else if ( bOk && nRefId == GDB_ID_GRID)
PL.LocToLoc( frCrv, pGeomDB->GetGridFrame()) ;
else if ( bOk && nRefId != nId) {
Frame3d frDest ;
// nRefId può essere un gruppo o una entità
if ( pGeomDB->GetGroupGlobFrame( nRefId, frDest) ||
pGeomDB->GetGlobFrame( nRefId, frDest))
PL.LocToLoc( frCrv, frDest) ;
else
bOk = false ;
}
// derivo il rettangolo in XY di area minima di questa
Point3d ptCen ;
Vector3d vtAx ;
bOk = bOk && PL.GetMinAreaRectangleXY( ptCen, vtAx, dDimX, dDimY) &&
frRect.Set( ptCen, Z_AX, vtAx) ;
return bOk ;
}
//----------------------------------------------------------------------------
int
ExeClosedCurveClassify( int nId1, int nId2)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, 0)
// recupero la prima curva
const ICurve* pCrv1 = GetCurve( pGeomDB->GetGeoObj( nId1)) ;
if ( pCrv1 == nullptr || ! pCrv1->IsClosed())
return CCREGC_NULL ;
// recupero il riferimento della curva
Frame3d frCrv1 ;
if ( ! pGeomDB->GetGlobFrame( nId1, frCrv1))
return CCREGC_NULL ;
// recupero la seconda curva
const ICurve* pCrv2 = GetCurve( pGeomDB->GetGeoObj( nId2)) ;
if ( pCrv2 == nullptr || ! pCrv2->IsClosed())
return CCREGC_NULL ;
// recupero il riferimento della curva
Frame3d frCrv2 ;
if ( ! pGeomDB->GetGlobFrame( nId2, frCrv2))
return CCREGC_NULL ;
// se riferimenti diversi, porto una copia della seconda nel riferimento della prima
const ICurve* pCrv2L = pCrv2 ;
PtrOwner<ICurve> pTmp ;
if ( ! AreSameFrame( frCrv1, frCrv2)) {
pTmp.Set( pCrv2->Clone()) ;
if ( IsNull( pTmp) || ! pTmp->LocToLoc( frCrv2, frCrv1))
return CCREGC_NULL ;
pCrv2L = pTmp ;
}
// classifico la prima curva rispetto alla seconda
IntersCurveCurve ccInt( *pCrv1, *pCrv2L) ;
return ccInt.GetRegionCurveClassification() ;
}
//----------------------------------------------------------------------------
bool
ExeArcRadius( int nId, double* pdRad)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( pdRad == nullptr)
return false ;
// recupero l'arco
const ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ;
if ( pArc == nullptr)
return false ;
*pdRad = pArc->GetRadius() ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExeArcAngCenter( int nId, double* pdAngDeg)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( pdAngDeg == nullptr)
return false ;
// recupero l'arco
const ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ;
if ( pArc == nullptr)
return false ;
*pdAngDeg = pArc->GetAngCenter() ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExeArcDeltaN( int nId, double* pdDeltaN)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( pdDeltaN == nullptr)
return false ;
// recupero l'arco
const ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ;
if ( pArc == nullptr)
return false ;
*pdDeltaN = pArc->GetDeltaN() ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExeArcNormVersor( int nId, int nRefId, Vector3d& vtNorm)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero l'arco
const ICurveArc* pArc = GetCurveArc( pGeomDB->GetGeoObj( nId)) ;
if ( pArc == nullptr)
return false ;
// recupero la normale
vtNorm = pArc->GetNormVersor() ;
// gestione trasformazione ( eventuale)
return TransformVector( pGeomDB, nId, nRefId, vtNorm) ;
}
//----------------------------------------------------------------------------
bool
ExeCurveCompoCenter( int nId, int nSimpCrv, int nRefId, Point3d& ptCen)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la curva composita
const ICurveComposite* pCompoCrv = GetCurveComposite( pGeomDB->GetGeoObj( nId)) ;
if ( pCompoCrv == nullptr)
return false ;
// recupero la curva semplice di indice richiesto
const ICurve* pSimpCrv = pCompoCrv->GetCurve( nSimpCrv) ;
if ( pSimpCrv == nullptr)
return false ;
// recupero il centro
if ( ! pSimpCrv->GetCenterPoint( ptCen))
return false ;
// gestione trasformazione ( eventuale)
return TransformPoint( pGeomDB, nId, nRefId, ptCen) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfArea( int nId, double& dArea)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( &dArea == nullptr)
return false ;
// recupero la superficie
ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( nId)) ;
// ne restituisco l'area
return ( pSurf != nullptr && pSurf->GetArea( dArea)) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfVolume( int nId, double& dVol)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( &dVol == nullptr)
return false ;
// recupero la superficie
ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( nId)) ;
// ne restituisco l'eventuale volume (se è chiusa)
return ( pSurf != nullptr && pSurf->GetVolume( dVol)) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfFrNormVersor( int nId, int nRefId, Vector3d& vtNorm)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la Regione
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
if ( pSfr == nullptr)
return false ;
// recupero la normale
vtNorm = pSfr->GetNormVersor() ;
// gestione trasformazione ( eventuale)
return TransformVector( pGeomDB, nId, nRefId, vtNorm) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfFrGrossArea( int nId, double& dArea)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( &dArea == nullptr)
return false ;
// recupero la Regione
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
// ne restituisco l'area senza eventuali buchi
return ( pSfr != nullptr && pSfr->GetGrossArea( dArea)) ;
}
//----------------------------------------------------------------------------
int
ExeSurfFrChunkCount( int nId)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, 0)
// recupero la regione
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ;
if ( pSfr == nullptr)
return false ;
// recupero il numero di chunk
return pSfr->GetChunkCount() ;
}
//----------------------------------------------------------------------------
int
ExeSurfFrChunkSimpleClassify( int nId1, int nChunk1, int nId2, int nChunk2)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, 0)
// recupero la prima superficie FlatRegion
ISurfFlatRegion* pSfr1 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId1)) ;
bool bOk = ( pSfr1 != nullptr) ;
// recupero il riferimento della superficie
Frame3d frSurf1 ;
bOk = bOk && pGeomDB->GetGlobFrame( nId1, frSurf1) ;
// recupero la seconda superficie FlatRegion
const ISurfFlatRegion* pSfr2 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId2)) ;
bOk = bOk && ( pSfr2 != nullptr) ;
// recupero il riferimento della superficie
Frame3d frSurf2 ;
bOk = bOk && pGeomDB->GetGlobFrame( nId2, frSurf2) ;
// se riferimenti diversi, porto una copia della seconda nel riferimento della prima
const ISurfFlatRegion* pSfr2L = pSfr2 ;
PtrOwner<ISurfFlatRegion> pTmp ;
if ( ! AreSameFrame( frSurf1, frSurf2)) {
pTmp.Set( pSfr2->Clone()) ;
bOk = bOk && ! IsNull( pTmp) ;
bOk = bOk && pTmp->LocToLoc( frSurf2, frSurf1) ;
pSfr2L = pTmp ;
}
// classifico il chunk della prima regione rispetto a quello della seconda
int nRes = ( bOk ? pSfr1->GetChunkSimpleClassification( nChunk1, *pSfr2L, nChunk2) : REGC_NULL) ;
return nRes ;
}
//----------------------------------------------------------------------------
bool
ExeSurfFrTestExternal( int nId1, int nId2, double dMinDist)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
// recupero la prima superficie FlatRegion
ISurfFlatRegion* pSfr1 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId1)) ;
if ( pSfr1 == nullptr)
return false ;
// se richiesta distanza di sicurezza, ne faccio l'offset
PtrOwner<ISurfFlatRegion> pSfr1O( pSfr1->Clone()) ;
if ( IsNull( pSfr1O))
return false ;
if ( dMinDist > 10 * EPS_SMALL)
pSfr1O->Offset( dMinDist, ICurve::OFF_FILLET) ;
// recupero il riferimento della superficie
Frame3d frSurf1 ;
if ( ! pGeomDB->GetGlobFrame( nId1, frSurf1))
return false ;
// recupero il tipo della seconda entità
int nType2 = pGeomDB->GetGeoType( nId2) ;
// se seconda entità regione
if ( nType2 == SRF_FLATRGN) {
// recupero la seconda superficie FlatRegion in locale alla prima
SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ;
const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ;
if ( pSfr2L == nullptr)
return false ;
// eseguo il test di intersezione tra le due regioni
for ( int i = 0 ; i < pSfr1O->GetChunkCount() ; ++ i) {
for ( int j = 0 ; j < pSfr2L->GetChunkCount() ; ++ j) {
if ( pSfr1O->GetChunkSimpleClassification( i, *pSfr2L, j) != REGC_OUT)
return false ;
}
}
return true ;
}
// se altrimenti curva
else if ( (nType2 & GEO_CURVE) != 0) {
// recupero la curva in locale alla regione
CurveLocal Crv2Loc( pGeomDB, nId2, frSurf1) ;
const ICurve* pCrv2L = Crv2Loc.Get() ;
if ( pCrv2L == nullptr)
return false ;
// eseguo il test di intersezione tra regione e curva
for ( int i = 0 ; i < pSfr1O->GetChunkCount() ; ++ i) {
PtrOwner<ICurve> pCrv1( pSfr1O->GetLoop( i, 0)) ;
if ( pCrv1 == nullptr)
return false ;
IntersCurveCurve ccInt( *pCrv1, *pCrv2L) ;
CRVCVECTOR vcClass ;
if ( ! ccInt.GetCurveClassification( 1, vcClass) || vcClass.empty())
return false ;
for ( auto& cClass : vcClass) {
if ( cClass.nClass == CRVC_IN || cClass.nClass == CRVC_NULL)
return false ;
}
}
return true ;
}
// altrimenti non valida
else
return false ;
}
//----------------------------------------------------------------------------
int
ExeSurfTmFacetCount( int nId)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, 0)
// recupero la superficie trimesh
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
if ( pStm == nullptr)
return 0 ;
// recupero il numero delle facce
return pStm->GetFacetCount() ;
}
//----------------------------------------------------------------------------
int
ExeSurfTmFacetFromTria( int nId, int nT)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, SVT_NULL)
// recupero la superficie trimesh
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
if ( pStm == nullptr)
return SVT_NULL ;
// recupero il numero della faccia da quello di un suo triangolo
return pStm->GetFacetFromTria( nT) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfTmFacetAdjacencies( int nId, int nFacet, INTMATRIX& vAdj)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL)
// recupero la superficie TriMesh
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
bool bOk = ( pStm != nullptr) ;
// recupero le adiacenze
bOk = bOk && pStm->GetFacetAdjacencies( nFacet, vAdj) ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
ExeSurfTmFacetNearestEndPoint( int nId, int nFacet, const Point3d& ptNear, int nRefId,
Point3d& ptEnd, Vector3d& vtN)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la superficie trimesh
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
if ( pStm == nullptr)
return false ;
// porto il punto Near nel riferimento dell'entità
Point3d ptNearL = ptNear ;
if ( ! InvTransformPoint( pGeomDB, nId, nRefId, ptNearL))
return false ;
// recupero il punto End più vicino della faccia
if ( ! pStm->GetFacetNearestEndPoint( nFacet, ptNearL, ptEnd, vtN))
return false ;
// gestione trasformazioni ( eventuali)
return TransformPoint( pGeomDB, nId, nRefId, ptEnd) && TransformVector( pGeomDB, nId, nRefId, vtN) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfTmFacetNearestMidPoint( int nId, int nFacet, const Point3d& ptNear, int nRefId,
Point3d& ptMid, Vector3d& vtN)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la superficie trimesh
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
if ( pStm == nullptr)
return false ;
// porto il punto Near nel riferimento dell'entità
Point3d ptNearL = ptNear ;
if ( ! InvTransformPoint( pGeomDB, nId, nRefId, ptNearL))
return false ;
// recupero il punto Mid più vicino della faccia
if ( ! pStm->GetFacetNearestMidPoint( nFacet, ptNearL, ptMid, vtN))
return false ;
// gestione trasformazioni ( eventuali)
return TransformPoint( pGeomDB, nId, nRefId, ptMid) && TransformVector( pGeomDB, nId, nRefId, vtN) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfTmFacetCenter( int nId, int nFacet, int nRefId, Point3d& ptCen, Vector3d& vtN)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la superficie trimesh
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
if ( pStm == nullptr)
return false ;
// recupero il centro della faccia
if ( ! pStm->GetFacetCenter( nFacet, ptCen, vtN))
return false ;
// gestione trasformazioni ( eventuali)
return TransformPoint( pGeomDB, nId, nRefId, ptCen) && TransformVector( pGeomDB, nId, nRefId, vtN) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfTmFacetNormVersor( int nId, int nFacet, int nRefId, Vector3d& vtNorm)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la superficie trimesh
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
if ( pStm == nullptr)
return false ;
// recupero il centro della faccia
if ( ! pStm->GetFacetNormal( nFacet, vtNorm))
return false ;
// gestione trasformazione ( eventuale)
return TransformVector( pGeomDB, nId, nRefId, vtNorm) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfTmFacetMinAreaRectangle( int nId, int nFacet, int nRefId, Frame3d& frRect, double& dDimX, double& dDimY)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la superficie trimesh
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
if ( pStm == nullptr)
return false ;
// recupero il centro e la normale della faccia
Point3d ptCen ; Vector3d vtN ;
if ( ! pStm->GetFacetCenter( nFacet, ptCen, vtN))
return false ;
// calcolo il riferimento OCS della faccia
Frame3d frFac ;
if ( ! frFac.Set( ptCen, vtN))
return false ;
// recupero il contorno esterno della faccia e lo porto nel suo riferimento
POLYLINEVECTOR vPL ;
pStm->GetFacetLoops( nFacet, vPL) ;
if ( vPL.empty())
return false ;
vPL[0].ToLoc( frFac) ;
// derivo il rettangolo in XY di area minima di questa
Point3d ptOri ;
Vector3d vtAx ;
if ( ! vPL[0].GetMinAreaRectangleXY( ptOri, vtAx, dDimX, dDimY) || ! frRect.Set( ptOri, Z_AX, vtAx))
return false ;
// esprimo il riferimento rispetto a quello richiesto
frRect.ToGlob( frFac) ;
return TransformFrame( pGeomDB, nId, nRefId, frRect) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfTmFacetOppositeSide( int nId, int nFacet, const Vector3d& vtDir, int nRefId,
Point3d& ptP1, Point3d& ptP2)
{
Point3d ptPm ;
Vector3d vtIn1, vtOut2;
double dLen, dWidth ;
return ExeSurfTmFacetOppositeSideEx( nId, nFacet, vtDir, nRefId, ptP1, ptPm, ptP2, vtIn1, vtOut2, dLen, dWidth) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfTmFacetOppositeSideEx( int nId, int nFacet, const Vector3d& vtDir, int nRefId,
Point3d& ptP1, Point3d& ptPm, Point3d& ptP2, Vector3d& vtIn1, Vector3d& vtOut2, double& dLen, double& dWidth)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero il riferimento della trimesh
Frame3d frStm ;
if ( ! pGeomDB->GetGlobFrame( nId, frStm))
return false ;
// recupero la superficie trimesh
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
if ( pStm == nullptr)
return false ;
// recupero i contorni della faccia
POLYLINEVECTOR vPL ;
pStm->GetFacetLoops( nFacet, vPL) ;
if ( vPL.empty())
return false ;
// recupero la normale esterna della faccia
Point3d ptCen ;
Vector3d vtN ;
if ( ! pStm->GetFacetCenter( nFacet, ptCen, vtN))
return false ;
// creo la curva a partire dal contorno esterno
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( vPL[0]))
return false ;
// unisco parti allineate
pCrvCompo->MergeCurves( LIN_TOL_STD, ANG_TOL_STD_DEG) ;
// porto la direzione nel riferimento della superficie
Vector3d vtDirL = vtDir ;
if ( ! InvTransformVector( pGeomDB, nId, nRefId, vtDirL))
return false ;
// costruisco un riferimento con Z su normale e X vicino a direzione
Frame3d frSpec ;
if ( ! frSpec.Set( ptCen, vtN, vtDirL))
return false ;
// porto il contorno in questo riferimento
pCrvCompo->ToLoc( frSpec) ;
// ne faccio una copia per usi successivi
PtrOwner<ICurveComposite> pCrvCopy( pCrvCompo->Clone()) ;
// la direzione di riferimento è l'asse X, la sostituisco con quella perpendicolare alla curva più adatta
Vector3d vtRef = X_AX ;
double dCosMax = -1 ;
const ICurve* pCrv = pCrvCompo->GetFirstCurve() ;
while ( pCrv != nullptr) {
Vector3d vtDir ; pCrv->GetMidDir( vtDir) ;
Vector3d vtPerp = Z_AX ^ vtDir ;
double dCos = vtPerp * X_AX ;
if ( dCos > dCosMax) {
dCosMax = dCos ;
vtRef = vtPerp ;
}
pCrv = pCrvCompo->GetNextCurve() ;
}
// la curva gira in senso antiorario attorno al contorno faccia vista dalla normale uscente
// elimino i segmenti che hanno la direzione di riferimento a destra o quasi (46deg)
const double COS_ANG_MAX = cos( 46 * DEGTORAD) ;
const double MIN_DIR_LEN = 0.999 ;
// cerco primo elemento del contorno non valido e vi pongo inizio/fine della curva
int i = 0 ;
pCrv = pCrvCompo->GetFirstCurve() ;
while ( pCrv != nullptr) {
double dCrvLen = 0 ; pCrv->GetLength( dCrvLen) ;
Vector3d vtDir ; pCrv->GetMidDir( vtDir) ;
if ( dCrvLen > MIN_DIR_LEN && ( Z_AX ^ vtDir) * vtRef < COS_ANG_MAX) {
vtIn1 = vtDir ;
vtOut2 = vtDir ;
pCrvCompo->ChangeStartPoint( i) ;
break ;
}
pCrv = pCrvCompo->GetNextCurve() ;
++ i ;
}
// se non trovato almeno un lato non valido, errore
if ( pCrv == nullptr)
return false ;
// a partire da questo elimino elementi non validi in avanti e indietro
pCrv = pCrvCompo->GetFirstCurve() ;
while ( pCrv != nullptr) {
Vector3d vtDir ; pCrv->GetMidDir( vtDir) ;
if ( ( Z_AX ^ vtDir) * vtRef < COS_ANG_MAX) {
double dCrvLen = 0 ; pCrv->GetLength( dCrvLen) ;
if ( dCrvLen > MIN_DIR_LEN)
pCrv->GetMidDir( vtIn1) ;
delete( pCrvCompo->RemoveFirstOrLastCurve( false)) ;
pCrv = pCrvCompo->GetFirstCurve() ;
}
else
break ;
}
pCrv = pCrvCompo->GetLastCurve() ;
while ( pCrv != nullptr) {
Vector3d vtDir ; pCrv->GetMidDir( vtDir) ;
if ( ( Z_AX ^ vtDir) * vtRef < COS_ANG_MAX) {
double dCrvLen = 0 ; pCrv->GetLength( dCrvLen) ;
if ( dCrvLen > MIN_DIR_LEN)
pCrv->GetMidDir( vtOut2) ;
delete( pCrvCompo->RemoveFirstOrLastCurve( true)) ;
pCrv = pCrvCompo->GetLastCurve() ;
}
else
break ;
}
// elimino le curve estreme molto corte ( 0.1 mm)
const double REF_LEN = 10.0 ;
double dCompoLen ;
if ( pCrvCompo->GetLength( dCompoLen) && dCompoLen > REF_LEN) {
const double MIN_LEN = 0.1 ;
double dCrvLen ;
pCrv = pCrvCompo->GetFirstCurve() ;
if ( pCrv != nullptr && pCrv->GetLength( dCrvLen) && dCrvLen < MIN_LEN)
delete( pCrvCompo->RemoveFirstOrLastCurve( false)) ;
pCrv = pCrvCompo->GetLastCurve() ;
if ( pCrv != nullptr && pCrv->GetLength( dCrvLen) && dCrvLen < MIN_LEN)
delete( pCrvCompo->RemoveFirstOrLastCurve( true)) ;
}
// recupero i punti estremi della curva
if ( ! pCrvCompo->GetStartPoint( ptP1) || ! pCrvCompo->GetEndPoint( ptP2))
return false ;
// ricavo il punto intermedio
if ( pCrvCompo->GetCurveCount() == 1)
ptPm = Media( ptP1, ptP2, 0.5) ;
else if ( pCrvCompo->GetCurveCount() == 2)
pCrvCompo->GetPointD1D2( 1.0, ICurve::FROM_MINUS, ptPm) ;
else {
double dLen ;
pCrvCompo->GetLength( dLen) ;
double dU ;
pCrvCompo->GetParamAtLength( 0.5 * dLen, dU) ;
pCrvCompo->GetPointD1D2( dU, ICurve::FROM_MINUS, ptPm) ;
}
// determino la lunghezza e l'elevazione della faccia rispetto alla curva trovata
Vector3d vtTg = ptP2 - ptP1 ;
Frame3d frExtr ;
if ( ! frExtr.Set( ORIG, Z_AX, vtTg) || ! frExtr.Invert())
return false ;
BBox3d b3Extr ; pCrvCopy->GetBBox( frExtr, b3Extr) ;
if ( ! b3Extr.IsEmpty()) {
dLen = b3Extr.GetMax().x - b3Extr.GetMin().x ;
dWidth = b3Extr.GetMax().y - b3Extr.GetMin().y ;
}
else {
dLen = 0 ;
dWidth = 0 ;
}
// porto i punti nel riferimento della superficie e poi in quello richiesto
ptP1.ToGlob( frSpec) ;
ptPm.ToGlob( frSpec) ;
ptP2.ToGlob( frSpec) ;
vtIn1.ToGlob( frSpec) ;
vtOut2.ToGlob( frSpec) ;
return ( TransformPoint( pGeomDB, nId, nRefId, ptP1) &&
TransformPoint( pGeomDB, nId, nRefId, ptPm) &&
TransformPoint( pGeomDB, nId, nRefId, ptP2) &&
TransformVector( pGeomDB, nId, nRefId, vtIn1) &&
TransformVector( pGeomDB, nId, nRefId, vtOut2)) ;
}
//----------------------------------------------------------------------------
bool
ExeSurfTmFacetsContact( int nId, int nF1, int nF2, int nRefId, bool& bAdjac, Point3d& ptP1, Point3d& ptP2, double& dAng)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero la superficie trimesh
const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ;
if ( pStm == nullptr)
return false ;
// recupero i dati di contatto tra le due facce
if ( ! pStm->GetFacetsContact( nF1, nF2, bAdjac, ptP1, ptP2, dAng))
return false ;
// gestione trasformazione ( eventuale)
if ( bAdjac)
return TransformPoint( pGeomDB, nId, nRefId, ptP1) && TransformPoint( pGeomDB, nId, nRefId, ptP2) ;
else
return true ;
}
//----------------------------------------------------------------------------
bool
ExeVolZmapVolume( int nId, double& dVol)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( &dVol == nullptr)
return false ;
// recupero il solido Zmap
const IVolZmap* pVZM = GetVolZmap( pGeomDB->GetGeoObj( nId)) ;
// ne restituisco il volume
return ( pVZM != nullptr && pVZM->GetVolume( dVol)) ;
}
//----------------------------------------------------------------------------
int
ExeVolZmapPartCount( int nId)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, -1)
// recupero il solido Zmap
const IVolZmap* pVZM = GetVolZmap( pGeomDB->GetGeoObj( nId)) ;
if ( pVZM == nullptr)
return -1 ;
// recupero il numero di parti
return pVZM->GetPartCount() ;
}
//----------------------------------------------------------------------------
bool
ExeVolZmapPartVolume( int nId, int nPart, double& dVol)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico il parametro
if ( &dVol == nullptr)
return false ;
// recupero il solido Zmap
const IVolZmap* pVZM = GetVolZmap( pGeomDB->GetGeoObj( nId)) ;
// restituisco il volume della eventuale parte richiesta
return ( pVZM != nullptr && pVZM->GetPartVolume( nPart, dVol)) ;
}
//----------------------------------------------------------------------------
bool
ExeTextNormVersor( int nId, int nRefId, Vector3d& vtNorm)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero il testo
const IExtText* pTxt = GetExtText( pGeomDB->GetGeoObj( nId)) ;
if ( pTxt == nullptr)
return false ;
// recupero la normale
vtNorm = pTxt->GetNormVersor() ;
// gestione trasformazione ( eventuale)
return TransformVector( pGeomDB, nId, nRefId, vtNorm) ;
}
//----------------------------------------------------------------------------
bool
ExeTextGetContent( int nId, string& sText)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero il testo
const IExtText* pTxt = GetExtText( pGeomDB->GetGeoObj( nId)) ;
if ( pTxt == nullptr)
return false ;
// recupero il contenuto
sText = pTxt->GetText() ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExeTextGetFont( int nId, string& sFont)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero il testo
const IExtText* pTxt = GetExtText( pGeomDB->GetGeoObj( nId)) ;
if ( pTxt == nullptr)
return false ;
// recupero il font
sFont = pTxt->GetFont() ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExeTextGetHeight( int nId, double& dH)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero il testo
const IExtText* pTxt = GetExtText( pGeomDB->GetGeoObj( nId)) ;
if ( pTxt == nullptr)
return false ;
// recupero l'altezza
dH = pTxt->GetHeight() ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExeTextGetItalic( int nId, bool& bItl)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// recupero il testo
const IExtText* pTxt = GetExtText( pGeomDB->GetGeoObj( nId)) ;
if ( pTxt == nullptr)
return false ;
// recupero l'altezza
bItl = pTxt->GetItalic() ;
return true ;
}
//-------------------------------------------------------------------------------
// Geo Transforms
//-------------------------------------------------------------------------------
bool
ExePointToIdGlob( Point3d& ptP, int nId)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se griglia
if ( nId == GDB_ID_GRID)
return ptP.ToGlob( pGeomDB->GetGridFrame()) ;
// recupero il riferimento
// se gruppo -> il suo proprio espresso in globale
// se oggetto -> quello del gruppo cui appartiene in globale
Frame3d frRef ;
if ( ! pGeomDB->GetGroupGlobFrame( nId, frRef) &&
! pGeomDB->GetGlobFrame( nId, frRef))
return false ;
// eseguo la trasformazione
return ptP.ToGlob( frRef) ;
}
//-------------------------------------------------------------------------------
bool
ExePointToIdLoc( Point3d& ptP, int nId)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se griglia
if ( nId == GDB_ID_GRID)
return ptP.ToLoc( pGeomDB->GetGridFrame()) ;
// recupero il riferimento
// se gruppo -> il suo proprio espresso in globale
// se oggetto -> quello del gruppo cui appartiene in globale
Frame3d frRef ;
if ( ! pGeomDB->GetGroupGlobFrame( nId, frRef) &&
! pGeomDB->GetGlobFrame( nId, frRef))
return false ;
// eseguo la trasformazione
return ptP.ToLoc( frRef) ;
}
//-------------------------------------------------------------------------------
bool
ExeVectorToIdGlob( Vector3d& vtV, int nId)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se griglia
if ( nId == GDB_ID_GRID)
return vtV.ToGlob( pGeomDB->GetGridFrame()) ;
// recupero il riferimento
// se gruppo -> il suo proprio espresso in globale
// se oggetto -> quello del gruppo cui appartiene in globale
Frame3d frRef ;
if ( ! pGeomDB->GetGroupGlobFrame( nId, frRef) &&
! pGeomDB->GetGlobFrame( nId, frRef))
return false ;
// eseguo la trasformazione
return vtV.ToGlob( frRef) ;
}
//-------------------------------------------------------------------------------
bool
ExeVectorToIdLoc( Vector3d& vtV, int nId)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se griglia
if ( nId == GDB_ID_GRID)
return vtV.ToLoc( pGeomDB->GetGridFrame()) ;
// recupero il riferimento
// se gruppo -> il suo proprio espresso in globale
// se oggetto -> quello del gruppo cui appartiene in globale
Frame3d frRef ;
if ( ! pGeomDB->GetGroupGlobFrame( nId, frRef) &&
! pGeomDB->GetGlobFrame( nId, frRef))
return false ;
// eseguo la trasformazione
return vtV.ToLoc( frRef) ;
}