0ca47c7bef
- in export DXF e STL gestite anche le regioni - in import BTL aggiunto flag per mettere i pezzi di piatto - in import BTL aggiynto al pezzo testo con nome.
839 lines
33 KiB
C++
839 lines
33 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2015
|
|
//----------------------------------------------------------------------------
|
|
// File : BtlGeom.cpp Data : 26.08.15 Versione : 1.6h5
|
|
// Contenuto : Implementazione delle funzioni sui processi per BtlGeom.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 27.08.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "BtlGeom.h"
|
|
#include "Polygon3d.h"
|
|
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
|
#include "/EgtDev/Include/EGkExtText.h"
|
|
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
#define IS_CUT( nG, nP) ( ( nGroup == 1 || nGroup == 2) && nProc == 10)
|
|
#define IS_LONGIT_CUT( nG, nP) ( ( nGroup == 0 || nGroup == 3 || nGroup == 4) && nProc == 10)
|
|
#define IS_DOUBLE_CUT( nG, nP) ( ( nGroup == 1 || nGroup == 2) && nProc == 11)
|
|
#define IS_RIDGEVALLEY_CUT( nG, nP) ( ( nGroup == 0) && nProc == 12)
|
|
#define IS_LAP_JOINT( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 30)
|
|
#define IS_NOTCH( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 32)
|
|
#define IS_SEATHING_CUT( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 34)
|
|
#define IS_TEXT( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 61)
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline double
|
|
Clip( double dVal, double dMin, double dMax)
|
|
{
|
|
return ( ( dVal < dMin) ? dMin : ( ( dVal > dMax) ? dMax : dVal)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::GetProcessParamInfos( int nGroup, int nProc, int nSide,
|
|
INTVECTOR& vnDPar, int& nSPar, DBLVECTOR& vdPar, string& sPar)
|
|
{
|
|
// se taglio
|
|
if ( IS_CUT( nGroup, nProc)) {
|
|
vnDPar.reserve( 5) ; vdPar.reserve( 5) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 2) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 3) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 6) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 90) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se taglio longitudinale
|
|
if ( IS_LONGIT_CUT( nGroup, nProc)) {
|
|
vnDPar.reserve( 8) ; vdPar.reserve( 8) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 2) ; vdPar.emplace_back( 20) ;
|
|
vnDPar.emplace_back( 4) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 45) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 90) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se taglio doppio
|
|
if ( IS_DOUBLE_CUT( nGroup, nProc)) {
|
|
vnDPar.reserve( 6) ; vdPar.reserve( 6) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 2) ; vdPar.emplace_back( 50) ;
|
|
vnDPar.emplace_back( 6) ; vdPar.emplace_back( 45) ;
|
|
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 8) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 90) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se taglio doppio longitudinale
|
|
if ( IS_RIDGEVALLEY_CUT( nGroup, nProc)) {
|
|
vnDPar.reserve( 11) ; vdPar.reserve( 11) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 2) ; vdPar.emplace_back( 0.5 * GetSideWidth( nSide)) ;
|
|
vnDPar.emplace_back( 4) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 45) ;
|
|
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 45) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 16) ; vdPar.emplace_back( 90) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se mezzo-legno
|
|
if ( IS_LAP_JOINT( nGroup, nProc)) {
|
|
vnDPar.reserve( 13) ; vdPar.reserve( 13) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 2) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 3) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 4) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 6) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 8) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 0.5 * GetSideHeight( nSide)) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 100) ;
|
|
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se scanalatura
|
|
if ( IS_NOTCH( nGroup, nProc)) {
|
|
vnDPar.reserve( 6) ; vdPar.reserve( 6) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 2) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 4) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 20) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 20) ;
|
|
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 200) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se taglio per rivestimento
|
|
if ( IS_SEATHING_CUT( nGroup, nProc)) {
|
|
vnDPar.reserve( 3) ; vdPar.reserve( 3) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 1) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( GetSideLength( nSide)) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se testo
|
|
if ( IS_TEXT( nGroup, nProc)) {
|
|
vnDPar.reserve( 8) ; vdPar.reserve( 8) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 2) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 6) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 200) ;
|
|
nSPar = 15 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddProcess( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const DBLVECTOR& vdPar, const string& sPar)
|
|
{
|
|
// se taglio
|
|
if ( IS_CUT( nGroup, nProc))
|
|
return AddCut( nGroup, nProc, nSide, sDes, nProcId, vdPar) ;
|
|
// se taglio longitudinale
|
|
if ( IS_LONGIT_CUT( nGroup, nProc))
|
|
return AddLongitCut( nGroup, nProc, nSide, sDes, nProcId, vdPar) ;
|
|
// se doppio taglio
|
|
if ( IS_DOUBLE_CUT( nGroup, nProc))
|
|
return AddDoubleCut( nGroup, nProc, nSide, sDes, nProcId, vdPar) ;
|
|
// se doppio taglio longitudinale
|
|
if ( IS_RIDGEVALLEY_CUT( nGroup, nProc))
|
|
return AddRidgeValleyCut( nGroup, nProc, nSide, sDes, nProcId, vdPar) ;
|
|
// se mezzo-legno
|
|
if ( IS_LAP_JOINT( nGroup, nProc))
|
|
return AddLapJoint( nGroup, nProc, nSide, sDes, nProcId, vdPar) ;
|
|
// se scanalatura
|
|
if ( IS_NOTCH( nGroup, nProc))
|
|
return AddNotch( nGroup, nProc, nSide, sDes, nProcId, vdPar) ;
|
|
// se taglio per rivestimento
|
|
if ( IS_SEATHING_CUT( nGroup, nProc))
|
|
return AddSeathingCut( nGroup, nProc, nSide, sDes, nProcId, vdPar) ;
|
|
// se testo
|
|
if ( IS_TEXT( nGroup, nProc))
|
|
return AddText( nGroup, nProc, nSide, sDes, nProcId, vdPar, sPar) ;
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddCut( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 5)
|
|
return false ;
|
|
// sistemo i dati
|
|
Point3d ptP( vdPar[0], vdPar[1], vdPar[2]) ;
|
|
double dAngle = Clip( vdPar[3], 0.1, 179.9) ;
|
|
double dInclination = Clip( vdPar[4], 0.1, 179.9) ;
|
|
// calcolo la normale alla faccia del taglio
|
|
Vector3d vtN = FromSpherical( 1, 180 + dInclination, dAngle - 90) ;
|
|
if ( nGroup == 1)
|
|
vtN.Mirror( X_AX) ;
|
|
// creo il poligono di taglio
|
|
Polygon3d plyCut ;
|
|
if ( ! CreatePolygonInBox( ptP, vtN, nSide, plyCut))
|
|
return false ;
|
|
// creo la trimesh con questo contorno
|
|
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStm) || ! pStm->CreateByFlatContour( plyCut.GetPolyLine()))
|
|
return false ;
|
|
// inserisco la superficie nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddLongitCut( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 8)
|
|
return false ;
|
|
// sistemo i dati
|
|
Point3d ptP( vdPar[0], vdPar[1], 0) ;
|
|
int nLimits = lround( vdPar[2]) ;
|
|
double dInclination = Clip( vdPar[3], -90, 90) ;
|
|
double dStart = vdPar[0] ;
|
|
double dLength = vdPar[5] ;
|
|
// calcolo la normale alla faccia del taglio
|
|
Vector3d vtN = FromSpherical( 1, dInclination, - 90) ;
|
|
// creo il poligono di taglio
|
|
Polygon3d plyCut ;
|
|
if ( ! CreatePolygonInBox( ptP, vtN, nSide, plyCut))
|
|
return false ;
|
|
// eventuali limiti longitudinali
|
|
bool bStartLimited = false ;
|
|
bool bEndLimited = false ;
|
|
if ( dLength > EPS_SMALL) {
|
|
if ( dStart > EPS_SMALL && ( nLimits == 0 || nLimits == 1 || nLimits == 5))
|
|
bStartLimited = true ;
|
|
if ( ( dStart + dLength < m_vtDim.x - EPS_SMALL) && ( nLimits == 0 || nLimits == 1 || nLimits == 3))
|
|
bEndLimited = true ;
|
|
}
|
|
Polygon3d plyStart ;
|
|
if ( bStartLimited) {
|
|
// creo il poligono di inizio
|
|
if ( ! CreatePolygonInBox( Point3d( dStart, 0, 0), X_AX, BTL_SIDE_NONE, plyStart))
|
|
return false ;
|
|
// trimmo tra loro taglio e inizio
|
|
if ( ! plyCut.Trim( plyStart, false, true) || ! plyStart.Trim( plyCut, false, false))
|
|
return false ;
|
|
}
|
|
Polygon3d plyEnd ;
|
|
if ( bEndLimited) {
|
|
// creo il poligono di fine
|
|
if ( ! CreatePolygonInBox( Point3d( dStart + dLength, 0, 0), -X_AX, BTL_SIDE_NONE, plyEnd))
|
|
return false ;
|
|
// trimmo tra loro taglio e fine
|
|
if ( ! plyCut.Trim( plyEnd, false, true) || ! plyEnd.Trim( plyCut, false, false))
|
|
return false ;
|
|
}
|
|
// creo la trimesh dalle due facce
|
|
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
if ( ! DoSewing( Get( pStm), plyCut) ||
|
|
! DoSewing( Get( pStm), plyStart) ||
|
|
! DoSewing( Get( pStm), plyEnd))
|
|
return false ;
|
|
pStm->DoCompacting() ;
|
|
// inserisco la superficie nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddDoubleCut( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 6)
|
|
return false ;
|
|
// sistemo i dati
|
|
Point3d ptP( vdPar[0], vdPar[1], 0) ;
|
|
double dAngle1 = Clip( vdPar[2], 0.1, 179.9) ;
|
|
double dInclination1 = Clip( vdPar[3], 0.1, 179.9) ;
|
|
double dAngle2 = Clip( vdPar[4], 0.1, 179.9) ;
|
|
double dInclination2 = Clip( vdPar[5], 0.1, 179.9) ;
|
|
// creo il primo poligono di taglio
|
|
Polygon3d plyCut1 ;
|
|
Vector3d vtN1 = FromSpherical( 1, 180 + dInclination1, dAngle1 - 90) ;
|
|
if ( nGroup == 1)
|
|
vtN1.Mirror( X_AX) ;
|
|
if ( ! CreatePolygonInBox( ptP, vtN1, nSide, plyCut1))
|
|
return false ;
|
|
// creo il secondo poligono di taglio
|
|
Polygon3d plyCut2 ;
|
|
Vector3d vtN2 = FromSpherical( 1, 180 + dInclination2, dAngle2 - 90) ;
|
|
if ( nGroup == 1)
|
|
vtN2.Mirror( X_AX) ;
|
|
if ( ! CreatePolygonInBox( ptP, vtN2, nSide, plyCut2))
|
|
return false ;
|
|
// trimmo tra loro le due facce
|
|
bool bInVsOut = ( dAngle2 <= dAngle1) ;
|
|
if ( ! plyCut1.Trim( plyCut2, bInVsOut, true) || ! plyCut2.Trim( plyCut1, bInVsOut, false))
|
|
return false ;
|
|
// creo la trimesh dalle due facce
|
|
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
if ( ! DoSewing( Get( pStm), plyCut1) ||
|
|
! DoSewing( Get( pStm), plyCut2))
|
|
return false ;
|
|
pStm->DoCompacting() ;
|
|
// inserisco la superficie nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddRidgeValleyCut( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 11)
|
|
return false ;
|
|
// sistemo i dati
|
|
double dStart = vdPar[0] ;
|
|
double dMid = vdPar[1] ;
|
|
double dDepth = Clip( vdPar[5], 0, 50000) ;
|
|
int nLimits = lround( vdPar[2]) ;
|
|
double dInclination1 = Clip( vdPar[3], -89.9, 89.9) ;
|
|
double dInclination2 = Clip( vdPar[4], -89.9, 89.9) ;
|
|
double dLength = vdPar[6] ;
|
|
Point3d ptP( dStart, dMid, - dDepth) ;
|
|
// calcolo la prima faccia del taglio
|
|
Polygon3d plyCut1 ;
|
|
Vector3d vtN1 = FromSpherical( 1, dInclination1, - 90) ;
|
|
if ( ! CreatePolygonInBox( ptP, vtN1, nSide, plyCut1))
|
|
return false ;
|
|
// calcolo la seconda faccia del taglio
|
|
Polygon3d plyCut2 ;
|
|
Vector3d vtN2 = FromSpherical( 2, - dInclination2, - 90) ;
|
|
if ( ! CreatePolygonInBox( ptP, vtN2, nSide, plyCut2))
|
|
return false ;
|
|
// trimmo le facce tra loro
|
|
bool bInVsOut = ( dInclination1 + dInclination2 >= 0) ;
|
|
if ( ! plyCut1.Trim( plyCut2, bInVsOut, true) || ! plyCut2.Trim( plyCut1, bInVsOut, false))
|
|
return false ;
|
|
// faccia longitudinale di servizio di separazione tra i tagli
|
|
Polygon3d plyLong ;
|
|
if ( ! CreatePolygonInBox( Point3d( 0, dMid, 0), - Y_AX, nSide, plyLong))
|
|
return false ;
|
|
// eventuali limiti sulla lunghezza
|
|
bool bStartLimited = false ;
|
|
bool bEndLimited = false ;
|
|
if ( dLength > EPS_SMALL) {
|
|
if ( dStart > EPS_SMALL && ( nLimits == 0 || nLimits == 1 || nLimits == 5))
|
|
bStartLimited = true ;
|
|
if ( ( dStart + dLength < m_vtDim.x - EPS_SMALL) && ( nLimits == 0 || nLimits == 1 || nLimits == 3))
|
|
bEndLimited = true ;
|
|
}
|
|
Polygon3d plyStart1, plyStart2 ;
|
|
if ( bStartLimited) {
|
|
// poligono di inizio per primo taglio
|
|
if ( plyCut1.GetSideCount() > 0) {
|
|
if ( ! CreatePolygonInBox( Point3d( dStart, 0, 0), X_AX, BTL_SIDE_NONE, plyStart1))
|
|
return false ;
|
|
// lo limito solo se esiste anche il taglio 2
|
|
if ( plyCut2.GetSideCount() > 0)
|
|
plyStart1.Trim( plyLong, false, false) ;
|
|
if ( ! plyCut1.Trim( plyStart1, false, true) || ! plyStart1.Trim( plyCut1, false, false))
|
|
return false ;
|
|
}
|
|
// poligono di inizio per secondo taglio
|
|
if ( plyCut2.GetSideCount() > 0) {
|
|
if ( ! CreatePolygonInBox( Point3d( dStart, 0, 0), X_AX, BTL_SIDE_NONE, plyStart2))
|
|
return false ;
|
|
// lo limito solo se esiste anche il taglio 1
|
|
if ( plyCut1.GetSideCount() > 0)
|
|
plyStart2.Trim( plyLong, true, false) ;
|
|
if ( ! plyCut2.Trim( plyStart2, false, true) || ! plyStart2.Trim( plyCut2, false, false))
|
|
return false ;
|
|
}
|
|
}
|
|
Polygon3d plyEnd1, plyEnd2 ;
|
|
if ( bEndLimited) {
|
|
// poligono di fine per primo taglio
|
|
if ( plyCut1.GetSideCount() > 0) {
|
|
if ( ! CreatePolygonInBox( Point3d( dStart + dLength, 0, 0), -X_AX, BTL_SIDE_NONE, plyEnd1))
|
|
return false ;
|
|
// lo limito solo se esiste anche il taglio 2
|
|
if ( plyCut2.GetSideCount() > 0)
|
|
plyEnd1.Trim( plyLong, false, false) ;
|
|
if ( ! plyCut1.Trim( plyEnd1, false, true) || ! plyEnd1.Trim( plyCut1, false, false))
|
|
return false ;
|
|
}
|
|
// poligono di fine per secondo taglio
|
|
if ( plyCut2.GetSideCount() > 0) {
|
|
if ( ! CreatePolygonInBox( Point3d( dStart + dLength, 0, 0), -X_AX, BTL_SIDE_NONE, plyEnd2))
|
|
return false ;
|
|
// lo limito solo se esiste anche il taglio 1
|
|
if ( plyCut1.GetSideCount() > 0)
|
|
plyEnd2.Trim( plyLong, true, false) ;
|
|
if ( ! plyCut2.Trim( plyEnd2, false, true) || ! plyEnd2.Trim( plyCut2, false, false))
|
|
return false ;
|
|
}
|
|
}
|
|
// creo la trimesh dalle diverse facce
|
|
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
if ( ! DoSewing( Get( pStm), plyCut1) ||
|
|
! DoSewing( Get( pStm), plyStart1) ||
|
|
! DoSewing( Get( pStm), plyEnd1) ||
|
|
! DoSewing( Get( pStm), plyCut2) ||
|
|
! DoSewing( Get( pStm), plyStart2) ||
|
|
! DoSewing( Get( pStm), plyEnd2))
|
|
return false ;
|
|
pStm->DoCompacting() ;
|
|
// inserisco la superficie nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddLapJoint( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 13)
|
|
return false ;
|
|
// sistemo i dati
|
|
double dStartX = vdPar[0] ;
|
|
double dStartY = vdPar[1] ;
|
|
double dStartZ = - Clip( vdPar[2], 0, 50000) ;
|
|
double dAngle = Clip( vdPar[4], 0.1, 179.9) ;
|
|
double dInclination = Clip( vdPar[5], 0.1, 179.9) ;
|
|
double dLeadAngle = Clip( vdPar[7], 0, 179.9) ;
|
|
double dLeadIncl = Clip( vdPar[8], 0, 179.9) ;
|
|
double dDepth = vdPar[9] ;
|
|
double dLength = Clip( vdPar[10], 1, 99999) ;
|
|
double dWidth = ( ( vdPar[12] > EPS_SMALL) ? vdPar[12] : GetSideWidth( nSide) - dStartY) ;
|
|
Point3d ptP( dStartX, dStartY, dStartZ) ;
|
|
// faccia di inizio
|
|
Polygon3d plyStart ;
|
|
Vector3d vtN1 = FromSpherical( 1, 180 - dInclination, 90 - dAngle) ;
|
|
if ( nGroup == 3)
|
|
vtN1.Mirror( X_AX) ;
|
|
if ( ! CreatePolygonInBox( ptP, vtN1, nSide, plyStart))
|
|
return false ;
|
|
// faccia di fine
|
|
Polygon3d plyEnd ;
|
|
if ( ! CreatePolygonInBox( ptP + dLength * vtN1, - vtN1, nSide, plyEnd))
|
|
return false ;
|
|
// facce davanti e dietro
|
|
Polygon3d plyFront, plyBack ;
|
|
if ( dLeadAngle < EPS_ANG_SMALL && dLeadIncl < EPS_ANG_SMALL) {
|
|
// se esistono, sono parallele ai lati adiacenti al side
|
|
if ( dStartY > EPS_SMALL) {
|
|
if ( ! CreatePolygonInBox( ptP, Y_AX, nSide, plyFront))
|
|
return false ;
|
|
}
|
|
if ( dStartY + dWidth < GetSideWidth( nSide) - EPS_SMALL) {
|
|
if ( ! CreatePolygonInBox( ptP + dWidth * Y_AX, - Y_AX, nSide, plyBack))
|
|
return false ;
|
|
}
|
|
}
|
|
else {
|
|
// se esistono, fisso dLeadAngle = 90 e dLeadIncl = 90
|
|
Vector3d vtN2 = FromSpherical( 1, 90, 180 - dAngle) ;
|
|
if ( dStartY > EPS_SMALL) {
|
|
if ( ! CreatePolygonInBox( ptP, vtN2, nSide, plyFront))
|
|
return false ;
|
|
}
|
|
if ( dStartY + dWidth < GetSideWidth( nSide) - EPS_SMALL) {
|
|
double dDeltaX = - dWidth * cos( dAngle * DEGTORAD) / sin( dAngle * DEGTORAD) ;
|
|
if ( nGroup == 3)
|
|
dDeltaX = - dDeltaX ;
|
|
if ( ! CreatePolygonInBox( ptP + dDeltaX * X_AX + dWidth * Y_AX, - vtN2, nSide, plyBack))
|
|
return false ;
|
|
}
|
|
}
|
|
// trim tra queste facce
|
|
if ( ! plyStart.Trim( plyFront, false, true) || ! plyFront.Trim( plyStart, false, false))
|
|
return false ;
|
|
if ( ! plyStart.Trim( plyBack, false, true) || ! plyBack.Trim( plyStart, false, false))
|
|
return false ;
|
|
if ( ! plyEnd.Trim( plyFront, false, true) || ! plyFront.Trim( plyEnd, false, false))
|
|
return false ;
|
|
if ( ! plyEnd.Trim( plyBack, false, true) || ! plyBack.Trim( plyEnd, false, false))
|
|
return false ;
|
|
// faccia sopra
|
|
Polygon3d plyTop ;
|
|
Vector3d vtN3 = FromSpherical( 1, 90 - dInclination, 90 - dAngle) ;
|
|
if ( nGroup == 3)
|
|
vtN3.Mirror( X_AX) ;
|
|
if ( dStartZ < - EPS_SMALL) {
|
|
if ( ! CreatePolygonInBox( ptP, - vtN3, nSide, plyTop))
|
|
return false ;
|
|
}
|
|
// trim con le altre facce
|
|
if ( ! plyStart.Trim( plyTop, false, true) || ! plyTop.Trim( plyStart, false, false))
|
|
return false ;
|
|
if ( ! plyEnd.Trim( plyTop, false, true) || ! plyTop.Trim( plyEnd, false, false))
|
|
return false ;
|
|
if ( ! plyFront.Trim( plyTop, false, true) || ! plyTop.Trim( plyFront, false, false))
|
|
return false ;
|
|
if ( ! plyBack.Trim( plyTop, false, true) || ! plyTop.Trim( plyBack, false, false))
|
|
return false ;
|
|
// faccia di fondo
|
|
Polygon3d plyBottom ;
|
|
double dDist = dDepth / sin( dInclination * DEGTORAD) ;
|
|
if ( ! CreatePolygonInBox( ptP - dDist * vtN3, vtN3, nSide, plyBottom))
|
|
return false ;
|
|
// trim con le altre facce
|
|
if ( ! plyStart.Trim( plyBottom, false, true) || ! plyBottom.Trim( plyStart, false, false))
|
|
return false ;
|
|
if ( ! plyEnd.Trim( plyBottom, false, true) || ! plyBottom.Trim( plyEnd, false, false))
|
|
return false ;
|
|
if ( ! plyFront.Trim( plyBottom, false, true) || ! plyBottom.Trim( plyFront, false, false))
|
|
return false ;
|
|
if ( ! plyBack.Trim( plyBottom, false, true) || ! plyBottom.Trim( plyBack, false, false))
|
|
return false ;
|
|
// creo la trimesh con questi contorni
|
|
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
DoSewing( Get( pStm), plyStart) ;
|
|
DoSewing( Get( pStm), plyEnd) ;
|
|
DoSewing( Get( pStm), plyFront) ;
|
|
DoSewing( Get( pStm), plyBack) ;
|
|
DoSewing( Get( pStm), plyTop) ;
|
|
DoSewing( Get( pStm), plyBottom) ;
|
|
pStm->DoCompacting() ;
|
|
// inserisco la superficie nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddNotch( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 6)
|
|
return false ;
|
|
// sistemo i dati
|
|
double dDepth = Clip( vdPar[3], 0, 50000) ;
|
|
double dLength = Clip( vdPar[4], 1, 99999) ;
|
|
double dWidth = Clip( vdPar[5], 1, 50000) ;
|
|
Point3d ptP( vdPar[0], vdPar[1] - 0.5 * dWidth, 0) ;
|
|
// faccia di inizio
|
|
Polygon3d plyStart ;
|
|
Vector3d vtN1 = X_AX ;
|
|
if ( nGroup == 3)
|
|
vtN1.Mirror( X_AX) ;
|
|
if ( ! CreatePolygonInBox( ptP, vtN1, nSide, plyStart))
|
|
return false ;
|
|
// faccia di fine
|
|
Polygon3d plyEnd ;
|
|
if ( ! CreatePolygonInBox( ptP + dLength * vtN1, - vtN1, nSide, plyEnd))
|
|
return false ;
|
|
// faccia davanti
|
|
Polygon3d plyFront ;
|
|
if ( ! CreatePolygonInBox( ptP, Y_AX, nSide, plyFront))
|
|
return false ;
|
|
// faccia dietro
|
|
Polygon3d plyBack ;
|
|
if ( ! CreatePolygonInBox( ptP + dWidth * Y_AX, - Y_AX, nSide, plyBack))
|
|
return false ;
|
|
// trim tra queste facce
|
|
if ( ! plyStart.Trim( plyFront, false, true) || ! plyFront.Trim( plyStart, false, false))
|
|
return false ;
|
|
if ( ! plyStart.Trim( plyBack, false, true) || ! plyBack.Trim( plyStart, false, false))
|
|
return false ;
|
|
if ( ! plyEnd.Trim( plyFront, false, true) || ! plyFront.Trim( plyEnd, false, false))
|
|
return false ;
|
|
if ( ! plyEnd.Trim( plyBack, false, true) || ! plyBack.Trim( plyEnd, false, false))
|
|
return false ;
|
|
// faccia di fondo
|
|
Polygon3d plyBottom ;
|
|
if ( ! CreatePolygonInBox( ptP - dDepth * Z_AX, Z_AX, nSide, plyBottom))
|
|
return false ;
|
|
// trim con le altre facce
|
|
if ( ! plyStart.Trim( plyBottom, false, true) || ! plyBottom.Trim( plyStart, false, false))
|
|
return false ;
|
|
if ( ! plyEnd.Trim( plyBottom, false, true) || ! plyBottom.Trim( plyEnd, false, false))
|
|
return false ;
|
|
if ( ! plyFront.Trim( plyBottom, false, true) || ! plyBottom.Trim( plyFront, false, false))
|
|
return false ;
|
|
if ( ! plyBack.Trim( plyBottom, false, true) || ! plyBottom.Trim( plyBack, false, false))
|
|
return false ;
|
|
// creo la trimesh con questi contorni
|
|
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
DoSewing( Get( pStm), plyStart) ;
|
|
DoSewing( Get( pStm), plyEnd) ;
|
|
DoSewing( Get( pStm), plyFront) ;
|
|
DoSewing( Get( pStm), plyBack) ;
|
|
DoSewing( Get( pStm), plyBottom) ;
|
|
pStm->DoCompacting() ;
|
|
// inserisco la superficie nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddSeathingCut( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 3)
|
|
return false ;
|
|
// sistemo i dati
|
|
Point3d ptP( vdPar[0], 0, 0) ;
|
|
double dDepth = Clip( vdPar[1], 0, GetSideHeight( nSide)) ;
|
|
double dLength = Clip( vdPar[2], 1, 99999) ;
|
|
// faccia di inizio
|
|
Polygon3d plyStart ;
|
|
Vector3d vtN1 = X_AX ;
|
|
if ( nGroup == 3)
|
|
vtN1.Mirror( X_AX) ;
|
|
if ( ! CreatePolygonInBox( ptP, vtN1, nSide, plyStart))
|
|
return false ;
|
|
// faccia di fine
|
|
Polygon3d plyEnd ;
|
|
if ( ! CreatePolygonInBox( ptP + dLength * vtN1, - vtN1, nSide, plyEnd))
|
|
return false ;
|
|
// faccia di fondo
|
|
Polygon3d plyBottom ;
|
|
if ( ! CreatePolygonInBox( ptP - dDepth * Z_AX, Z_AX, nSide, plyBottom))
|
|
return false ;
|
|
// trim tra le facce
|
|
if ( ! plyStart.Trim( plyBottom, false, true) || ! plyBottom.Trim( plyStart, false, false))
|
|
return false ;
|
|
if ( ! plyEnd.Trim( plyBottom, false, true) || ! plyBottom.Trim( plyEnd, false, false))
|
|
return false ;
|
|
// creo la trimesh con questi contorni
|
|
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
DoSewing( Get( pStm), plyStart) ;
|
|
DoSewing( Get( pStm), plyEnd) ;
|
|
DoSewing( Get( pStm), plyBottom) ;
|
|
pStm->DoCompacting() ;
|
|
// inserisco la superficie nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddText( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const DBLVECTOR& vdPar, const string& sPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 8 || sPar.empty())
|
|
return false ;
|
|
// sistemo i dati
|
|
Point3d ptP( vdPar[0], vdPar[1], 0) ;
|
|
Vector3d vtD = FromPolar( 1, vdPar[2]) ;
|
|
double dH = vdPar[7] ;
|
|
int nInsPos ;
|
|
switch ( lround( vdPar[3])) {
|
|
case 0 :
|
|
switch ( lround( vdPar[4])) {
|
|
case 0 : nInsPos = ETXT_IPBL ; break ;
|
|
case 1 : nInsPos = ETXT_IPBC ; break ;
|
|
case 2 : nInsPos = ETXT_IPBR ; break ;
|
|
}
|
|
break ;
|
|
case 1 :
|
|
switch ( lround( vdPar[4])) {
|
|
case 0 : nInsPos = ETXT_IPML ; break ;
|
|
case 1 : nInsPos = ETXT_IPMC ; break ;
|
|
case 2 : nInsPos = ETXT_IPMR ; break ;
|
|
}
|
|
break ;
|
|
case 2 :
|
|
switch ( lround( vdPar[4])) {
|
|
case 0 : nInsPos = ETXT_IPTL ; break ;
|
|
case 1 : nInsPos = ETXT_IPTC ; break ;
|
|
case 2 : nInsPos = ETXT_IPTR ; break ;
|
|
}
|
|
break ;
|
|
}
|
|
// non � gestito P11 (giustificazione su multilinea)
|
|
// assegno il testo
|
|
string sText ;
|
|
if ( lround( vdPar[6]) == 0)
|
|
sText = sPar ;
|
|
// rotazione dei caratteri di 90 gradi
|
|
else {
|
|
// ruoto la direzione di riferimento
|
|
vtD.Rotate( Z_AX, 90) ;
|
|
// inserisco un a capo dopo ogni carattere, tranne l'ultimo
|
|
size_t nChar = sPar.size() ;
|
|
for ( size_t i = 0 ; i < nChar - 1 ; ++ i)
|
|
sText += sPar[i] + ETXT_LINEBREAK ;
|
|
sText += sPar[nChar-1] ;
|
|
// sistemo il tipo di inserimento
|
|
switch ( nInsPos) {
|
|
case ETXT_IPTL : nInsPos = ETXT_IPTR ; break ;
|
|
case ETXT_IPTC : nInsPos = ETXT_IPMR ; break ;
|
|
case ETXT_IPTR : nInsPos = ETXT_IPBR ; break ;
|
|
case ETXT_IPML : nInsPos = ETXT_IPTC ; break ;
|
|
case ETXT_IPMC : break ;
|
|
case ETXT_IPMR : nInsPos = ETXT_IPBC ; break ;
|
|
case ETXT_IPBL : nInsPos = ETXT_IPTL ; break ;
|
|
case ETXT_IPBC : nInsPos = ETXT_IPML ; break ;
|
|
case ETXT_IPBR : nInsPos = ETXT_IPBL ; break ;
|
|
}
|
|
}
|
|
// creo il testo
|
|
PtrOwner<IExtText> pText( CreateExtText()) ;
|
|
if ( IsNull( pText))
|
|
return false ;
|
|
// assegno i dati
|
|
if ( ! pText->Set( ptP, Z_AX, vtD, sText, "", 100, false, dH, 1, 0, nInsPos))
|
|
return false ;
|
|
// porto il testo nel piano della faccia
|
|
Frame3d frRef = GetSideFrame( nSide) ;
|
|
pText->ToGlob( frRef) ;
|
|
// inserisco il testo nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pText)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
// colore per linee di marcatura e testi
|
|
m_pGDB->SetMaterial( nId, m_MarkCol) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::CreatePolygonInBox( const Point3d& ptP, const Vector3d& vtN, int nSide, Polygon3d& Polyg)
|
|
{
|
|
// calcolo il piano
|
|
Plane3d plPlane ;
|
|
if ( ! SetPlane( ptP, vtN, plPlane))
|
|
return false ;
|
|
// trasformo il piano per faccia di inserimento
|
|
if ( nSide != BTL_SIDE_NONE) {
|
|
Frame3d frRef = GetSideFrame( nSide) ;
|
|
plPlane.ToGlob( frRef) ;
|
|
}
|
|
// creo il poligono, limitandolo al box dell'oggetto (trave/parete)
|
|
return Polyg.FromPlaneTrimmedWithBox( plPlane, ORIG, ORIG + m_vtDim) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::DoSewing( ISurfTriMesh* pStm, const Polygon3d& Polyg)
|
|
{
|
|
// verifico esistenza superficie
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// se poligono vuoto, non devo fare alcunch�
|
|
if ( Polyg.GetSideCount() == 0)
|
|
return true ;
|
|
// creo la superficie trimesh del poligono
|
|
PtrOwner<ISurfTriMesh> pStm2( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStm2) || ! pStm2->CreateByFlatContour( Polyg.GetPolyLine()))
|
|
return false ;
|
|
// le unisco
|
|
return pStm->DoSewing( *pStm2) ;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::SetNameAndInfo( int nId, int nGroup, int nProc, int nSide, const string& sDes, int nProcId)
|
|
{
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome
|
|
string sName ;
|
|
if ( nProcId != 0)
|
|
sName = ToString( nProcId) ;
|
|
if ( ! sDes.empty())
|
|
sName += "-" + sDes ;
|
|
m_pGDB->SetName( nId, sName) ;
|
|
// info con tipo
|
|
m_pGDB->SetInfo( nId, IKEY_GROUP, nGroup) ;
|
|
m_pGDB->SetInfo( nId, IKEY_PROC, nProc) ;
|
|
m_pGDB->SetInfo( nId, IKEY_SIDE, nSide) ;
|
|
return true ;
|
|
}
|