0a2e602e79
- correzioni in import BTL a AddLapJoint e a AddMortiseFront.
2437 lines
100 KiB
C++
2437 lines
100 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2017
|
|
//----------------------------------------------------------------------------
|
|
// File : BtlGeomProc.cpp Data : 20.03.17 Versione : 1.8c3
|
|
// Contenuto : Implementazione delle funzioni sui processi per BtlGeom.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 27.08.15 DS Creazione modulo.
|
|
// 05.12.16 DS Agg. import forature.
|
|
// 12.03.17 DS Agg. import tenoni e mortase.
|
|
// 20.03.17 DS Agg. import tenoni e mortase a coda di rondine.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "DllMain.h"
|
|
#include "BtlGeom.h"
|
|
#include "Polygon3d.h"
|
|
#include "/EgtDev/Include/EGkCurveLine.h"
|
|
#include "/EgtDev/Include/EGkCurveArc.h"
|
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkExtText.h"
|
|
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
|
#include "/EgtDev/Include/EGkSfrCreate.h"
|
|
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
|
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
|
#include "/EgtDev/Include/EGkIntervals.h"
|
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
|
#include "/EgtDev/Include/EgtNumUtils.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_DRILL( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 40)
|
|
#define IS_TENON( nG, nP) ( ( nGroup == 1 || nGroup == 2) && nProc == 50)
|
|
#define IS_MORTISE( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 50)
|
|
#define IS_MORTISE_FRONT( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 51)
|
|
#define IS_HOUSE( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 52)
|
|
#define IS_HOUSE_MORTISE( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 53)
|
|
#define IS_DOVETAIL_TENON( nG, nP) ( ( nGroup == 1 || nGroup == 2) && nProc == 55)
|
|
#define IS_DOVETAIL_MORTISE( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 55)
|
|
#define IS_DTMORTISE_FRONT( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 56)
|
|
#define IS_TEXT( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 61)
|
|
#define IS_FREE_CONTOUR( nG, nP) ( ( nGroup == 0 || nGroup == 3 || nGroup == 4) && nProc == 250)
|
|
|
|
//----------------------------------------------------------------------------
|
|
const double COS_ALMOST_PERP = cos( 85. * DEGTORAD) ;
|
|
const double LEN_EXTRUS_AGG = 50. ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::GetProcessParamInfos( int nGroup, int nProc, int nSide,
|
|
INTVECTOR& vnDPar, int& nSPar, DBLVECTOR& vdPar, string& sPar) const
|
|
{
|
|
// 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 foratura
|
|
if ( IS_DRILL( nGroup, nProc)) {
|
|
vnDPar.reserve( 7) ; vdPar.reserve( 7) ;
|
|
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( 45) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( GetSideHeight(nSide)) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 20) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se tenone
|
|
if ( IS_TENON( nGroup, nProc)) {
|
|
vnDPar.reserve( 12) ; vdPar.reserve( 12) ;
|
|
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( 5) ; 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( 90) ;
|
|
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 40) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 40) ;
|
|
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se mortasa
|
|
if ( IS_MORTISE( nGroup, nProc)) {
|
|
vnDPar.reserve( 14) ; vdPar.reserve( 14) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 2) ; vdPar.emplace_back( 0.5 * GetSideWidth( nSide)) ;
|
|
vnDPar.emplace_back( 3) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 4) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 6) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 8) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 40) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 40) ;
|
|
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 200) ;
|
|
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 16) ; vdPar.emplace_back( 90) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se mortasa sul fronte
|
|
if ( IS_MORTISE_FRONT( 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( 6) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 8) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 40) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 40) ;
|
|
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se avanzamento tenone
|
|
if ( IS_HOUSE( nGroup, nProc)) {
|
|
vnDPar.reserve( 13) ; vdPar.reserve( 13) ;
|
|
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( 5) ; 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( 90) ;
|
|
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 40) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 40) ;
|
|
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 0) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se avanzamento mortasa
|
|
if ( IS_HOUSE_MORTISE( nGroup, nProc)) {
|
|
vnDPar.reserve( 15) ; vdPar.reserve( 15) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 2) ; vdPar.emplace_back( 0.5 * GetSideWidth( nSide)) ;
|
|
vnDPar.emplace_back( 3) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 4) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 6) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 8) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 40) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 40) ;
|
|
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 200) ;
|
|
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 16) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 0) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se tenone a coda di rondine
|
|
if ( IS_DOVETAIL_TENON( nGroup, nProc)) {
|
|
vnDPar.reserve( 12) ; vdPar.reserve( 12) ;
|
|
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( 6) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 8) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 28) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 45) ;
|
|
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se mortasa a coda di rondine
|
|
if ( IS_DOVETAIL_MORTISE( nGroup, nProc)) {
|
|
vnDPar.reserve( 14) ; vdPar.reserve( 14) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 2) ; vdPar.emplace_back( 0.5 * GetSideWidth( nSide)) ;
|
|
vnDPar.emplace_back( 3) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 4) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 5) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 6) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 90) ;
|
|
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 28) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 45) ;
|
|
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 200) ;
|
|
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
// se mortasa a coda di rondine sul fronte
|
|
if ( IS_DTMORTISE_FRONT( nGroup, nProc)) {
|
|
vnDPar.reserve( 14) ; vdPar.reserve( 14) ;
|
|
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 2) ; vdPar.emplace_back( 0.5 * GetSideWidth( nSide)) ;
|
|
vnDPar.emplace_back( 3) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 4) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 5) ; 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( 90) ;
|
|
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 28) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 45) ;
|
|
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
|
|
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
|
|
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 ;
|
|
}
|
|
// se contorno libero
|
|
if ( IS_FREE_CONTOUR( nGroup, nProc)) {
|
|
vnDPar.reserve( 10) ; vdPar.reserve( 10) ;
|
|
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( 5) ; vdPar.emplace_back( GetSideHeight( nSide)) ;
|
|
vnDPar.emplace_back( 6) ; vdPar.emplace_back( 0) ;
|
|
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) ;
|
|
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 0) ;
|
|
nSPar = 0 ; sPar.empty() ;
|
|
return true ;
|
|
}
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddProcess( int nGroup, int nProc, int nSide, const string& sDes, int nProcId, const Frame3d& frRef,
|
|
const INTVECTOR& vnDPar, int nSPar, const DBLVECTOR& vdPar, const string& sPar)
|
|
{
|
|
// se taglio
|
|
if ( IS_CUT( nGroup, nProc))
|
|
return AddCut( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se taglio longitudinale
|
|
if ( IS_LONGIT_CUT( nGroup, nProc))
|
|
return AddLongitCut( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se doppio taglio
|
|
if ( IS_DOUBLE_CUT( nGroup, nProc))
|
|
return AddDoubleCut( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se doppio taglio longitudinale
|
|
if ( IS_RIDGEVALLEY_CUT( nGroup, nProc))
|
|
return AddRidgeValleyCut( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se mezzo-legno
|
|
if ( IS_LAP_JOINT( nGroup, nProc))
|
|
return AddLapJoint( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se scanalatura
|
|
if ( IS_NOTCH( nGroup, nProc))
|
|
return AddNotch( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se taglio per rivestimento
|
|
if ( IS_SEATHING_CUT( nGroup, nProc))
|
|
return AddSeathingCut( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se foratura
|
|
if ( IS_DRILL( nGroup, nProc))
|
|
return AddDrill( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se tenone
|
|
if ( IS_TENON( nGroup, nProc))
|
|
return AddTenon( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se mortasa
|
|
if ( IS_MORTISE( nGroup, nProc))
|
|
return AddMortise( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se mortasa sul fronte
|
|
if ( IS_MORTISE_FRONT( nGroup, nProc))
|
|
return AddMortiseFront( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se avanzamento tenone
|
|
if ( IS_HOUSE( nGroup, nProc)) {
|
|
nGroup = ( nGroup == 3 ? 1 : 2) ;
|
|
return AddTenon( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
}
|
|
// se avanzamento mortasa
|
|
if ( IS_HOUSE_MORTISE( nGroup, nProc))
|
|
return AddMortise( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se tenone a coda di rondine
|
|
if ( IS_DOVETAIL_TENON( nGroup, nProc))
|
|
return AddDovetailTenon( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se mortasa a coda di rondine
|
|
if ( IS_DOVETAIL_MORTISE( nGroup, nProc))
|
|
return AddDovetailMortise( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se mortasa a coda di rondine sul fronte
|
|
if ( IS_DTMORTISE_FRONT( nGroup, nProc))
|
|
return AddDtMortiseFront( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar) ;
|
|
// se testo
|
|
if ( IS_TEXT( nGroup, nProc))
|
|
return AddText( nGroup, nProc, nSide, sDes, nProcId, vnDPar, nSPar, vdPar, sPar) ;
|
|
// se contorno libero
|
|
if ( IS_FREE_CONTOUR( nGroup, nProc))
|
|
return AddFreeContour( nGroup, nProc, nSide, sDes, nProcId, frRef, vnDPar, nSPar, vdPar, sPar) ;
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddCut( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, 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 = Clamp( vdPar[3], 0.1, 179.9) ;
|
|
double dInclination = Clamp( 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 ;
|
|
// colore semitrasparente
|
|
SetAlpha( nId, 80) ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddLongitCut( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, 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 = Clamp( 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( pStm, plyCut) ||
|
|
! DoSewing( pStm, plyStart) ||
|
|
! DoSewing( 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) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddDoubleCut( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 6)
|
|
return false ;
|
|
// sistemo i dati
|
|
Point3d ptP( vdPar[0], vdPar[1], 0) ;
|
|
double dAngle1 = Clamp( vdPar[2], 0.1, 179.9) ;
|
|
double dInclination1 = Clamp( vdPar[3], 0.1, 179.9) ;
|
|
double dAngle2 = Clamp( vdPar[4], 0.1, 179.9) ;
|
|
double dInclination2 = Clamp( 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( pStm, plyCut1) ||
|
|
! DoSewing( 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 ;
|
|
// colore semitrasparente
|
|
SetAlpha( nId, 80) ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddRidgeValleyCut( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, 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 = Clamp( vdPar[5], 0., 50000.) ;
|
|
int nLimits = lround( vdPar[2]) ;
|
|
double dInclination1 = Clamp( vdPar[3], -89.9, 89.9) ;
|
|
double dInclination2 = Clamp( 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( pStm, plyCut1) ||
|
|
! DoSewing( pStm, plyStart1) ||
|
|
! DoSewing( pStm, plyEnd1) ||
|
|
! DoSewing( pStm, plyCut2) ||
|
|
! DoSewing( pStm, plyStart2) ||
|
|
! DoSewing( 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) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddLapJoint( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, 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 = - Clamp( vdPar[2], 0., 50000.) ;
|
|
int nFlag = int( vdPar[3]) ;
|
|
double dAngle = Clamp( vdPar[4], 0.1, 179.9) ;
|
|
double dInclination = Clamp( vdPar[5], 0.1, 179.9) ;
|
|
double dSlope = Clamp( vdPar[6], -89.9, 89.9) ;
|
|
double dLeadAngle = Clamp( vdPar[7], 0., 179.9) ;
|
|
double dLeadIncl = Clamp( vdPar[8], 0., 179.9) ;
|
|
double dDepth = vdPar[9] ;
|
|
double dLength = Clamp( 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 ( ( nGroup == 4 && (nFlag & 1) == 0) ||
|
|
( nGroup == 3 && (nFlag & 2) == 0)) {
|
|
if ( ! CreatePolygonInBox( ptP, vtN1, nSide, plyStart))
|
|
return false ;
|
|
}
|
|
// faccia di fine
|
|
Polygon3d plyEnd ;
|
|
if ( ( nGroup == 4 && (nFlag & 2) == 0) ||
|
|
( nGroup == 3 && (nFlag & 1) == 0)) {
|
|
if ( ! CreatePolygonInBox( ptP + dLength * vtN1, - vtN1, nSide, plyEnd))
|
|
return false ;
|
|
}
|
|
// normale alla faccia di fondo
|
|
Vector3d vtN3 = FromSpherical( 1, 90 - dInclination, 90 - dAngle) ;
|
|
Vector3d vtAx = - vtN1 ;
|
|
if ( nGroup == 3) {
|
|
vtN3.Mirror( X_AX) ;
|
|
vtAx.Invert() ;
|
|
}
|
|
vtN3.Rotate( vtAx, dSlope) ;
|
|
// facce davanti e dietro
|
|
Vector3d vtN2 ;
|
|
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 ;
|
|
}
|
|
vtN2 = Y_AX ;
|
|
}
|
|
else {
|
|
// sistemo eventuale default di angolo nullo
|
|
if ( dLeadAngle < EPS_ANG_SMALL)
|
|
dLeadAngle = ANG_RIGHT ;
|
|
if ( dLeadIncl < EPS_ANG_SMALL)
|
|
dLeadIncl = ANG_RIGHT ;
|
|
// calcolo la normale alle facce davanti e dietro
|
|
// vettore intersezione facce fondo e inizio
|
|
Vector3d vtInt = vtN3 ^ vtN1 ;
|
|
// ruoto questi vettori attorno alla normale del fondo di + e -dLeadAngle
|
|
Vector3d vtRef1f = vtInt ;
|
|
Vector3d vtRef1b = vtInt ;
|
|
if ( (nFlag & 4) != 0) {
|
|
vtRef1f.Rotate( vtN3, 180 - dLeadAngle) ;
|
|
vtRef1b.Rotate( vtN3, 180 + dLeadAngle) ;
|
|
}
|
|
else {
|
|
vtRef1f.Rotate( vtN3, dLeadAngle) ;
|
|
vtRef1b.Rotate( vtN3, - dLeadAngle) ;
|
|
}
|
|
// ruoto questo vettore attorno alla normale dell'inizio di dLeadIncl
|
|
Vector3d vtRef2 = vtInt ;
|
|
if ( (nFlag & 4) != 0)
|
|
vtRef2.Rotate( vtN1, 180 - dLeadIncl) ;
|
|
else
|
|
vtRef2.Rotate( vtN1, dLeadIncl) ;
|
|
// la normale alla faccia davanti � perpendicolare a vtRef1f e vtRef2
|
|
Vector3d vtN2f = vtRef1f ^ vtRef2 ;
|
|
vtN2f.Normalize() ;
|
|
if ( nGroup == 3)
|
|
vtN2f.Invert() ;
|
|
// la normale alla faccia dietro � perpendicolare a vtRef1b e vtRef2
|
|
Vector3d vtN2b = vtRef1b ^ vtRef2 ;
|
|
vtN2b.Normalize() ;
|
|
if ( nGroup == 3)
|
|
vtN2b.Invert() ;
|
|
// calcolo la faccia davanti
|
|
if ( (nFlag & 4) == 0)
|
|
CreatePolygonInBox( ptP, vtN2f, nSide, plyFront) ;
|
|
// calcolo la faccia dietro
|
|
double dDeltaX = - dWidth * cos( dAngle * DEGTORAD) / sin( dAngle * DEGTORAD) ;
|
|
if ( nGroup == 3)
|
|
dDeltaX = - dDeltaX ;
|
|
if ( (nFlag & 8) == 0)
|
|
CreatePolygonInBox( ptP + dDeltaX * X_AX + dWidth * Y_AX, vtN2b, nSide, plyBack) ;
|
|
vtN2 = vtN2f ;
|
|
}
|
|
// 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 ;
|
|
if ( dStartZ < - EPS_SMALL && (nFlag & 32) == 0) {
|
|
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 ;
|
|
Vector3d vtEdge = vtN1 ^ vtN2 ; vtEdge.Normalize() ;
|
|
double dDist = dDepth / vtEdge.z ;
|
|
if ( (nFlag & 16) == 0) {
|
|
if ( ! CreatePolygonInBox( ptP - dDist * vtEdge, 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( pStm, plyStart) ;
|
|
DoSewing( pStm, plyEnd) ;
|
|
DoSewing( pStm, plyFront) ;
|
|
DoSewing( pStm, plyBack) ;
|
|
DoSewing( pStm, plyTop) ;
|
|
DoSewing( 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) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddNotch( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 6)
|
|
return false ;
|
|
// sistemo i dati
|
|
double dDepth = Clamp( vdPar[3], 0., 50000.) ;
|
|
double dLength = Clamp( vdPar[4], 1., 99999.) ;
|
|
double dWidth = Clamp( 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( pStm, plyStart) ;
|
|
DoSewing( pStm, plyEnd) ;
|
|
DoSewing( pStm, plyFront) ;
|
|
DoSewing( pStm, plyBack) ;
|
|
DoSewing( 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) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddSeathingCut( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 3)
|
|
return false ;
|
|
// sistemo i dati
|
|
Point3d ptP( vdPar[0], 0, 0) ;
|
|
double dDepth = Clamp( vdPar[1], 0., GetSideHeight( nSide)) ;
|
|
double dLength = Clamp( 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( pStm, plyStart) ;
|
|
DoSewing( pStm, plyEnd) ;
|
|
DoSewing( 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) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddDrill( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 7)
|
|
return false ;
|
|
// sistemo i dati
|
|
Point3d ptP( vdPar[0], vdPar[1], - vdPar[2]) ;
|
|
double dAngHor = Clamp( vdPar[3], 0., 360.) ;
|
|
double dAngVert = Clamp( vdPar[4], 1., 179.) ;
|
|
double dDepth = vdPar[5] / sin( dAngVert * DEGTORAD) ;
|
|
double dRad = vdPar[6] / 2 ;
|
|
// calcolo la direzione esterna del foro
|
|
Vector3d vtN = Z_AX ;
|
|
// foro su una delle facce laterali
|
|
if ( abs( vdPar[2]) < EPS_SMALL) {
|
|
if ( nGroup == 4)
|
|
vtN = FromSpherical( 1, ANG_RIGHT - dAngVert, - dAngHor) ;
|
|
else
|
|
vtN = FromSpherical( 1, ANG_RIGHT - dAngVert, ANG_STRAIGHT - dAngHor) ;
|
|
}
|
|
// foro su una delle facce di testa
|
|
else {
|
|
if ( nGroup == 4) {
|
|
vtN = FromSpherical( 1, ANG_RIGHT - dAngVert, dAngHor) ;
|
|
vtN.Rotate( Y_AX, - ANG_RIGHT) ;
|
|
}
|
|
else {
|
|
vtN = FromSpherical( 1, ANG_RIGHT - dAngVert, ANG_STRAIGHT + dAngHor) ;
|
|
vtN.Rotate( Y_AX, ANG_RIGHT) ;
|
|
}
|
|
}
|
|
// creo la circonferenza
|
|
PtrOwner<ICurveArc> pArc( CreateCurveArc()) ;
|
|
if ( IsNull( pArc))
|
|
return false ;
|
|
// assegno i dati
|
|
if ( ! pArc->Set( ptP, vtN, dRad))
|
|
return false ;
|
|
pArc->SetExtrusion( vtN) ;
|
|
pArc->SetThickness( - dDepth) ;
|
|
// porto l'entit� nel piano della faccia
|
|
Frame3d frRef = GetSideFrame( nSide) ;
|
|
pArc->ToGlob( frRef) ;
|
|
Vector3d vtNG = pArc->GetNormVersor() ;
|
|
// verifico se inizio su faccia
|
|
Point3d ptStart = pArc->GetCenter() ;
|
|
bool bStartClosed = true ;
|
|
double dSinStart = 0 ;
|
|
for ( int i = BTL_SIDE_FRONT ; i <= BTL_SIDE_LEFT ; ++ i) {
|
|
Plane3d plSide = GetSidePlane( i) ;
|
|
if ( PointInPlaneApprox( ptStart, plSide) && vtNG * plSide.vtN > COS_ALMOST_PERP) {
|
|
bStartClosed = false ;
|
|
dSinStart = sqrt( max( 0., 1 - vtNG * plSide.vtN)) ;
|
|
break ;
|
|
}
|
|
}
|
|
double dStartAgg = (( bStartClosed || dSinStart < EPS_SMALL) ? 0 : dRad * dSinStart + LEN_EXTRUS_AGG) ;
|
|
// verifico se fine su faccia
|
|
Point3d ptEnd = ptStart - vtNG * dDepth ;
|
|
bool bEndClosed = true ;
|
|
double dSinEnd = 0 ;
|
|
for ( int i = BTL_SIDE_FRONT ; i <= BTL_SIDE_LEFT ; ++ i) {
|
|
Plane3d plSide = GetSidePlane( i) ;
|
|
if ( PointInPlaneApprox( ptEnd, plSide) && - vtNG * plSide.vtN > COS_ALMOST_PERP) {
|
|
bEndClosed = false ;
|
|
dSinEnd = sqrt( max( 0., 1 + vtNG * plSide.vtN)) ;
|
|
break ;
|
|
}
|
|
}
|
|
double dEndAgg = (( bEndClosed || dSinEnd < EPS_SMALL) ? 0 : dRad * dSinEnd + LEN_EXTRUS_AGG) ;
|
|
// approssimo la circonferenza con una spezzata
|
|
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
|
|
PolyLine PL ;
|
|
if ( ! pArc->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL) ||
|
|
! pCompo->FromPolyLine( PL))
|
|
return false ;
|
|
pCompo->SetExtrusion( vtNG) ;
|
|
// creo la superficie trimesh laterale del foro
|
|
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, - vtNG * ( dDepth + dStartAgg + dEndAgg)))
|
|
return false ;
|
|
pStm->Translate( vtNG * dStartAgg) ;
|
|
// se chiuso, creo la superficie trimesh di fondo del foro
|
|
if ( bEndClosed) {
|
|
PtrOwner<ISurfTriMesh> pStmBot( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmBot) || ! pStmBot->CreateByPointCurve( ptStart, PL))
|
|
return false ;
|
|
pStmBot->Translate( - vtNG * dDepth) ;
|
|
pStm->DoSewing( *pStmBot) ;
|
|
}
|
|
// eseguo trim con le facce della trave
|
|
TrimSurfTmWithBox( pStm) ;
|
|
// 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 ;
|
|
// inserisco la curva nel DB geometrico
|
|
int nTId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pArc)) ;
|
|
if ( nTId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// identificativi di geometrie ausiliarie
|
|
SetAuxId( nId, {nTId}) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddTenon( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 12)
|
|
return false ;
|
|
// sistemo i dati
|
|
Point3d ptP( vdPar[0], vdPar[1], 0) ;
|
|
int nFlag = int( vdPar[2]) ;
|
|
double dAngle = Clamp( vdPar[4], 0.1, 179.9) ;
|
|
double dInclination = Clamp( vdPar[5], 0.1, 179.9) ;
|
|
double dRot = Clamp( vdPar[6], 0.1, 179.9) ;
|
|
double dFillet = vdPar[7] ;
|
|
double dTenH = vdPar[8] ;
|
|
double dTenW = vdPar[9] ;
|
|
double dTenM1 = ( abs( vdPar[10]) < 10 * EPS_SMALL ? 10 * EPS_SMALL : vdPar[10]) ;
|
|
double dTenM2 = ( abs( vdPar[11]) < 10 * EPS_SMALL ? 10 * EPS_SMALL : vdPar[11]) ;
|
|
// 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 ;
|
|
// calcolo OCS
|
|
Frame3d frTen ;
|
|
frTen.Set( ptP, vtN, Z_AX ^ vtN) ;
|
|
frTen.Rotate( ptP, vtN, ( nGroup != 1 ? 90 - dRot : dRot - 90)) ;
|
|
frTen.ToGlob( GetSideFrame( nSide)) ;
|
|
// lunghezza del tenone
|
|
double dThick = GetSideHeight( nSide) ;
|
|
double dCosA = frTen.VersY() * GetSideVersN( nSide) ;
|
|
double dTenL = dThick / dCosA - dTenM1 - dTenM2 ;
|
|
// calcolo il centro del tenone
|
|
Point3d ptCen( 0, - dTenM1 - 0.5 * dTenL, 0) ;
|
|
ptCen.ToGlob( frTen) ;
|
|
// creo il contorno del tenone
|
|
double dTenHW = 0.5 * dTenW ;
|
|
PolyArc PA ;
|
|
if ( nFlag == 1) {
|
|
PA.AddUPoint( 0, Point3d( 0, - dTenM1, 0), 0) ;
|
|
PA.AddUPoint( 1, Point3d( - dTenHW, - dTenM1, 0), 0) ;
|
|
PA.AddUPoint( 2, Point3d( - dTenHW, - dTenM1 - dTenL, 0), 0) ;
|
|
PA.AddUPoint( 3, Point3d( dTenHW, - dTenM1 - dTenL, 0), 0) ;
|
|
PA.AddUPoint( 4, Point3d( dTenHW, - dTenM1, 0), 0) ;
|
|
PA.Close() ;
|
|
}
|
|
else {
|
|
const double BULGE_90D = tan( 90.0 / 4 * DEGTORAD) ;
|
|
double dRad = 0.5 * min( dTenW, dTenL) ;
|
|
if ( nFlag == 0 || nFlag == 3)
|
|
dRad = min( dRad, MILL_DEF_RAD) ;
|
|
else if ( nFlag == 4)
|
|
dRad = min( dRad, dFillet) ;
|
|
PA.AddUPoint( 0, Point3d( - dTenHW + dRad, - dTenM1, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 1, Point3d( - dTenHW, - dTenM1 - dRad, 0), 0) ;
|
|
PA.AddUPoint( 2, Point3d( - dTenHW, - dTenM1 - dTenL + dRad, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 3, Point3d( - dTenHW + dRad, - dTenM1 - dTenL, 0), 0) ;
|
|
PA.AddUPoint( 4, Point3d( dTenHW - dRad, - dTenM1 - dTenL, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 5, Point3d( dTenHW, - dTenM1 - dTenL + dRad, 0), 0) ;
|
|
PA.AddUPoint( 6, Point3d( dTenHW, - dTenM1 - dRad, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 7, Point3d( dTenHW - dRad, - dTenM1, 0), 0) ;
|
|
PA.Close() ;
|
|
}
|
|
PtrOwner<ICurveComposite> pCrvTen( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvTen) || ! pCrvTen->FromPolyArc( PA))
|
|
return false ;
|
|
pCrvTen->SetExtrusion( Z_AX) ;
|
|
pCrvTen->ToGlob( frTen) ;
|
|
// lo approssimo con una spezzata
|
|
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
|
|
PolyLine PL ;
|
|
if ( ! pCrvTen->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL) ||
|
|
! pCompo->FromPolyLine( PL))
|
|
return false ;
|
|
pCompo->SetExtrusion( frTen.VersZ()) ;
|
|
// creo la regione del contorno esterno
|
|
PtrOwner<ICurveComposite> pExt( CreateCurveComposite()) ;
|
|
if ( IsNull( pExt) || ! pExt->FromPolyLine( plyCut.GetPolyLine()))
|
|
return false ;
|
|
SurfFlatRegionByContours SfrExt ;
|
|
SfrExt.AddCurve( Release( pExt)) ;
|
|
PtrOwner<ISurfFlatRegion> pReg( SfrExt.GetSurf()) ;
|
|
if ( IsNull( pReg))
|
|
return false ;
|
|
// creo la regione del tenone
|
|
SurfFlatRegionByContours SfrTen ;
|
|
SfrTen.AddCurve( pCompo->Clone()) ;
|
|
PtrOwner<ISurfFlatRegion> pTen( SfrTen.GetSurf()) ;
|
|
if ( IsNull( pTen))
|
|
return false ;
|
|
// sottraggo la regione del tenone da quella esterna
|
|
if ( ! pReg->Subtract( *pTen))
|
|
return false ;
|
|
// ne deduco la superficie trimesh
|
|
PtrOwner<ISurfTriMesh> pStm( pReg->GetAuxSurf()->Clone()) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
// creo la superficie trimesh del tenone
|
|
PtrOwner<ISurfTriMesh> pStmTen( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmTen) || ! pStmTen->CreateByExtrusion( PL, frTen.VersZ() * dTenH))
|
|
return false ;
|
|
pStm->DoSewing( *pStmTen) ;
|
|
// creo la superficie trimesh di testa del tenone
|
|
PtrOwner<ISurfTriMesh> pStmCap( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmCap) || ! pStmCap->CreateByPointCurve( ptCen, PL))
|
|
return false ;
|
|
pStmCap->Translate( frTen.VersZ() * dTenH) ;
|
|
pStm->DoSewing( *pStmCap) ;
|
|
// eseguo trim con le facce della trave
|
|
TrimSurfTmWithBox( pStm) ;
|
|
// inserisco la superficie trimesh nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eseguo trim della curva con le facce della trave
|
|
TrimFlatCurveWithBox( pCrvTen) ;
|
|
// inserisco la curva nel DB geometrico
|
|
int nTId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvTen)) ;
|
|
if ( nTId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// identificativi di geometrie ausiliarie
|
|
SetAuxId( nId, {nTId}) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddMortise( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, 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 = - Clamp( vdPar[2], 0., 50000.) ;
|
|
int nFlag = int( vdPar[3]) ;
|
|
double dAngle = Clamp( vdPar[4], -180.0, 180.0) ;
|
|
double dSideIncl = Clamp( vdPar[6], 0.1, 179.9) ;
|
|
double dFrontIncl = Clamp( vdPar[13], 0.1, 179.9) ;
|
|
double dFillet = vdPar[7] ;
|
|
double dMortD = vdPar[8] ;
|
|
double dMortW = vdPar[9] ;
|
|
double dStrutAng = Clamp( vdPar[5], 0.1, 179.9) ;
|
|
double dMortM1 = vdPar[11] ;
|
|
double dMortM2 = vdPar[12] ;
|
|
double dMortL = Clamp( vdPar[10] / sin( dStrutAng * DEGTORAD) - dMortM1 - dMortM2, 1., 99999.) ;
|
|
Point3d ptP( dStartX, dStartY, dStartZ) ;
|
|
// calcolo la normale alla faccia di fondo
|
|
Vector3d vtN1 = FromSpherical( 1, 180 - dFrontIncl, dAngle) ;
|
|
if ( nGroup == 3)
|
|
vtN1.Mirror( X_AX) ;
|
|
double dSideAng = ( nGroup != 3 ? dSideIncl : 180 - dSideIncl) ;
|
|
Vector3d vtN2 = FromSpherical( 1, dSideAng, ANG_RIGHT + dAngle) ;
|
|
if ( nGroup == 3) {
|
|
vtN2.Mirror( X_AX) ;
|
|
vtN2.Invert() ;
|
|
}
|
|
Vector3d vtN3 = vtN1 ^ vtN2 ;
|
|
// calcolo riferimento della faccia di fondo
|
|
Frame3d frMort ;
|
|
frMort.Set( ptP - dMortD * vtN3, vtN3, vtN2) ;
|
|
frMort.ToGlob( GetSideFrame( nSide)) ;
|
|
// calcolo il centro della mortasa
|
|
Point3d ptCen( 0, - dMortM1 - 0.5 * dMortL, 0) ;
|
|
ptCen.ToGlob( frMort) ;
|
|
// creo il contorno della mortasa
|
|
double dMortHW = 0.5 * dMortW ;
|
|
PolyArc PA ;
|
|
if ( nFlag == 1) {
|
|
PA.AddUPoint( 0, Point3d( 0, - dMortM1, 0), 0) ;
|
|
PA.AddUPoint( 1, Point3d( - dMortHW, - dMortM1, 0), 0) ;
|
|
PA.AddUPoint( 2, Point3d( - dMortHW, - dMortM1 - dMortL, 0), 0) ;
|
|
PA.AddUPoint( 3, Point3d( dMortHW, - dMortM1 - dMortL, 0), 0) ;
|
|
PA.AddUPoint( 4, Point3d( dMortHW, - dMortM1, 0), 0) ;
|
|
PA.Close() ;
|
|
}
|
|
else {
|
|
const double BULGE_90D = tan( ANG_RIGHT / 4 * DEGTORAD) ;
|
|
double dRad = 0.5 * min( dMortW, dMortL) ;
|
|
if ( nFlag == 0 || nFlag == 3)
|
|
dRad = min( dRad, MILL_DEF_RAD) ;
|
|
else if ( nFlag == 4)
|
|
dRad = min( dRad, dFillet) ;
|
|
PA.AddUPoint( 0, Point3d( - dMortHW + dRad, - dMortM1, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 1, Point3d( - dMortHW, - dMortM1 - dRad, 0), 0) ;
|
|
PA.AddUPoint( 2, Point3d( - dMortHW, - dMortM1 - dMortL + dRad, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 3, Point3d( - dMortHW + dRad, - dMortM1 - dMortL, 0), 0) ;
|
|
PA.AddUPoint( 4, Point3d( dMortHW - dRad, - dMortM1 - dMortL, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 5, Point3d( dMortHW, - dMortM1 - dMortL + dRad, 0), 0) ;
|
|
PA.AddUPoint( 6, Point3d( dMortHW, - dMortM1 - dRad, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 7, Point3d( dMortHW - dRad, - dMortM1, 0), 0) ;
|
|
PA.Close() ;
|
|
}
|
|
PtrOwner<ICurveComposite> pCrvMort( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvMort) || ! pCrvMort->FromPolyArc( PA))
|
|
return false ;
|
|
pCrvMort->SetExtrusion( Z_AX) ;
|
|
pCrvMort->ToGlob( frMort) ;
|
|
// lo approssimo con una spezzata
|
|
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
|
|
PolyLine PL ;
|
|
if ( ! pCrvMort->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL) ||
|
|
! pCompo->FromPolyLine( PL))
|
|
return false ;
|
|
pCompo->SetExtrusion( frMort.VersZ()) ;
|
|
// creo la superficie trimesh di fondo della mortasa
|
|
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStm) || ! pStm->CreateByPointCurve( ptCen, PL))
|
|
return false ;
|
|
// creo la superficie trimesh laterale della mortasa
|
|
double dExtr = dMortD + ( dMortM1 + dMortL) * max( tan( ( ANG_RIGHT - dFrontIncl) * DEGTORAD), 0.) +
|
|
dMortHW * abs( tan( ( ANG_RIGHT - dSideIncl) * DEGTORAD)) ;
|
|
if ( abs( ANG_RIGHT - dFrontIncl) > EPS_ANG_SMALL || abs( ANG_RIGHT - dSideIncl) > EPS_ANG_SMALL)
|
|
dExtr += 50.0 ;
|
|
PtrOwner<ISurfTriMesh> pStmMort( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmMort) || ! pStmMort->CreateByExtrusion( PL, frMort.VersZ() * dExtr))
|
|
return false ;
|
|
pStmMort->Invert() ;
|
|
pStm->DoSewing( *pStmMort) ;
|
|
// eseguo trim con le facce della trave
|
|
TrimSurfTmWithBox( pStm) ;
|
|
// inserisco la superficie trimesh nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eseguo trim della curva con le facce della trave
|
|
TrimFlatCurveWithBox( pCrvMort) ;
|
|
// inserisco la curva nel DB geometrico
|
|
int nMId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvMort)) ;
|
|
if ( nMId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// identificativi di geometrie ausiliarie
|
|
SetAuxId( nId, {nMId}) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddMortiseFront( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 11)
|
|
return false ;
|
|
// sistemo i dati
|
|
Point3d ptP( vdPar[0], vdPar[1], 0) ;
|
|
int nFlag = int( vdPar[2]) ;
|
|
double dAngle = Clamp( vdPar[3], 0.1, 179.9) ;
|
|
double dInclination = Clamp( vdPar[4], 0.1, 179.9) ;
|
|
double dRot = Clamp( vdPar[5], 0.1, 179.9) ;
|
|
double dFillet = vdPar[6] ;
|
|
double dMortD = vdPar[7] ;
|
|
double dMortW = vdPar[8] ;
|
|
double dMortM1 = ( abs( vdPar[9]) < 10 * EPS_SMALL ? 10 * EPS_SMALL : vdPar[9]) ;
|
|
double dMortM2 = ( abs( vdPar[10]) < 10 * EPS_SMALL ? 10 * EPS_SMALL : vdPar[10]) ;
|
|
// calcolo la normale alla faccia del taglio
|
|
Vector3d vtN = FromSpherical( 1, 180 + dInclination, dAngle - 90) ;
|
|
if ( nGroup == 3)
|
|
vtN.Mirror( X_AX) ;
|
|
// creo il poligono di taglio
|
|
Polygon3d plyCut ;
|
|
if ( ! CreatePolygonInBox( ptP, vtN, nSide, plyCut))
|
|
return false ;
|
|
// calcolo OCS
|
|
Frame3d frMort ;
|
|
frMort.Set( ptP, vtN, Z_AX ^ vtN) ;
|
|
frMort.Rotate( ptP, vtN, ( nGroup != 3 ? 90 - dRot : dRot - 90)) ;
|
|
frMort.ToGlob( GetSideFrame( nSide)) ;
|
|
// lunghezza della mortasa
|
|
double dThick = GetSideHeight( nSide) ;
|
|
double dCosA = frMort.VersY() * GetSideVersN( nSide) ;
|
|
double dMortL = dThick / dCosA - dMortM1 - dMortM2 ;
|
|
// calcolo il centro della mortasa
|
|
Point3d ptCen( 0, - dMortM1 - 0.5 * dMortL, 0) ;
|
|
ptCen.ToGlob( frMort) ;
|
|
// creo il contorno della mortasa
|
|
double dMortHW = 0.5 * dMortW ;
|
|
PolyArc PA ;
|
|
if ( nFlag == 1) {
|
|
PA.AddUPoint( 0, Point3d( 0, - dMortM1, 0), 0) ;
|
|
PA.AddUPoint( 1, Point3d( - dMortHW, - dMortM1, 0), 0) ;
|
|
PA.AddUPoint( 2, Point3d( - dMortHW, - dMortM1 - dMortL, 0), 0) ;
|
|
PA.AddUPoint( 3, Point3d( dMortHW, - dMortM1 - dMortL, 0), 0) ;
|
|
PA.AddUPoint( 4, Point3d( dMortHW, - dMortM1, 0), 0) ;
|
|
PA.Close() ;
|
|
}
|
|
else {
|
|
const double BULGE_90D = tan( 90.0 / 4 * DEGTORAD) ;
|
|
double dRad = 0.5 * min( dMortW, dMortL) ;
|
|
if ( nFlag == 0 || nFlag == 3)
|
|
dRad = min( dRad, MILL_DEF_RAD) ;
|
|
else if ( nFlag == 4)
|
|
dRad = min( dRad, dFillet) ;
|
|
PA.AddUPoint( 0, Point3d( - dMortHW + dRad, - dMortM1, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 1, Point3d( - dMortHW, - dMortM1 - dRad, 0), 0) ;
|
|
PA.AddUPoint( 2, Point3d( - dMortHW, - dMortM1 - dMortL + dRad, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 3, Point3d( - dMortHW + dRad, - dMortM1 - dMortL, 0), 0) ;
|
|
PA.AddUPoint( 4, Point3d( dMortHW - dRad, - dMortM1 - dMortL, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 5, Point3d( dMortHW, - dMortM1 - dMortL + dRad, 0), 0) ;
|
|
PA.AddUPoint( 6, Point3d( dMortHW, - dMortM1 - dRad, 0), BULGE_90D) ;
|
|
PA.AddUPoint( 7, Point3d( dMortHW - dRad, - dMortM1, 0), 0) ;
|
|
PA.Close() ;
|
|
}
|
|
PtrOwner<ICurveComposite> pCrvTen( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvTen) || ! pCrvTen->FromPolyArc( PA))
|
|
return false ;
|
|
pCrvTen->SetExtrusion( Z_AX) ;
|
|
pCrvTen->ToGlob( frMort) ;
|
|
// lo approssimo con una spezzata
|
|
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
|
|
PolyLine PL ;
|
|
if ( ! pCrvTen->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL) ||
|
|
! pCompo->FromPolyLine( PL))
|
|
return false ;
|
|
pCompo->SetExtrusion( frMort.VersZ()) ;
|
|
// definisco la superficie
|
|
PtrOwner<ISurfTriMesh> pStm ;
|
|
// creo la regione del contorno esterno
|
|
PtrOwner<ICurveComposite> pExt( CreateCurveComposite()) ;
|
|
if ( IsNull( pExt))
|
|
return false ;
|
|
if ( pExt->FromPolyLine( plyCut.GetPolyLine())) {
|
|
SurfFlatRegionByContours SfrExt ;
|
|
SfrExt.AddCurve( Release( pExt)) ;
|
|
PtrOwner<ISurfFlatRegion> pReg( SfrExt.GetSurf()) ;
|
|
if ( IsNull( pReg))
|
|
return false ;
|
|
// creo la regione del tenone
|
|
SurfFlatRegionByContours SfrTen ;
|
|
SfrTen.AddCurve( pCompo->Clone()) ;
|
|
PtrOwner<ISurfFlatRegion> pTen( SfrTen.GetSurf()) ;
|
|
if ( IsNull( pTen))
|
|
return false ;
|
|
// sottraggo la regione del tenone da quella esterna
|
|
if ( ! pReg->Subtract( *pTen))
|
|
return false ;
|
|
// ne deduco la superficie trimesh
|
|
pStm.Set( pReg->GetAuxSurf()->Clone()) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
}
|
|
// creo la superficie trimesh della mortasa
|
|
PtrOwner<ISurfTriMesh> pStmTen( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmTen) || ! pStmTen->CreateByExtrusion( PL, - frMort.VersZ() * dMortD))
|
|
return false ;
|
|
if ( IsNull( pStm))
|
|
pStm.Set( Release( pStmTen)) ;
|
|
else
|
|
pStm->DoSewing( *pStmTen) ;
|
|
// creo la superficie trimesh di fondo della mortasa
|
|
PtrOwner<ISurfTriMesh> pStmCap( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmCap) || ! pStmCap->CreateByPointCurve( ptCen, PL))
|
|
return false ;
|
|
pStmCap->Translate( - frMort.VersZ() * dMortD) ;
|
|
pStm->DoSewing( *pStmCap) ;
|
|
// eseguo trim con le facce della trave
|
|
TrimSurfTmWithBox( pStm) ;
|
|
// inserisco la superficie trimesh nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eseguo trim della curva con le facce della trave
|
|
TrimFlatCurveWithBox( pCrvTen) ;
|
|
// inserisco la curva nel DB geometrico
|
|
int nTId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvTen)) ;
|
|
if ( nTId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// identificativi di geometrie ausiliarie
|
|
SetAuxId( nId, {nTId}) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddDovetailTenon( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 12)
|
|
return false ;
|
|
// sistemo i dati
|
|
Point3d ptP( vdPar[0], vdPar[1], 0) ;
|
|
int nFlag = int( vdPar[2]) ;
|
|
double dAngle = Clamp( vdPar[3], 0.1, 179.9) ;
|
|
double dInclination = Clamp( vdPar[4], 0.1, 179.9) ;
|
|
double dRot = Clamp( vdPar[5], 0.1, 179.9) ;
|
|
double dTenW = vdPar[6] ;
|
|
double dTenA = Clamp( vdPar[7], 0., 30.) ;
|
|
double dTenH = vdPar[8] ;
|
|
double dFillet = ( vdPar[9] > 10 * EPS_SMALL ? vdPar[9] / 2 : DTMILL_DEF_RAD) ;
|
|
double dTenM1 = ( abs( vdPar[10]) < 10 * EPS_SMALL ? 10 * EPS_SMALL : vdPar[10]) ;
|
|
double dTenM2 = ( abs( vdPar[11]) < 10 * EPS_SMALL ? 10 * EPS_SMALL : vdPar[11]) ;
|
|
// 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 ;
|
|
// calcolo OCS
|
|
Frame3d frTen ;
|
|
frTen.Set( ptP, vtN, Z_AX ^ vtN) ;
|
|
frTen.Rotate( ptP, vtN, ( nGroup != 1 ? 90 - dRot : dRot - 90)) ;
|
|
frTen.ToGlob( GetSideFrame( nSide)) ;
|
|
// lunghezza del tenone
|
|
double dThick = GetSideHeight( nSide) ;
|
|
double dCosA = frTen.VersY() * GetSideVersN( nSide) ;
|
|
double dTenL = dThick / dCosA - dTenM1 - dTenM2 ;
|
|
// calcolo il centro del tenone
|
|
Point3d ptCen( 0, - dTenM1 - 0.5 * dTenL, dTenH) ;
|
|
ptCen.ToGlob( frTen) ;
|
|
// creo il contorno basso del tenone
|
|
double dTenHW = 0.5 * dTenW ;
|
|
PolyArc PB ;
|
|
double dX0 = 0 ;
|
|
double dY0 = - dTenM1 - dTenL ;
|
|
PB.AddUPoint( 0, Point3d( dX0, dY0, 0), 0) ;
|
|
double dX1 = dTenW ;
|
|
double dY1 = dY0 ;
|
|
PB.AddUPoint( 1, Point3d( dX1, dY1, 0), 0) ;
|
|
double dX2 = dX1 + dFillet * cos( dTenA * DEGTORAD) ;
|
|
double dY2 = dY1 + dFillet * ( 1 - sin( dTenA * DEGTORAD)) ;
|
|
double dBulge2 = tan( ( ANG_RIGHT - dTenA) / 4 * DEGTORAD) ;
|
|
PB.ModifyLastBulge( dBulge2) ;
|
|
PB.AddUPoint( 2, Point3d( dX2, dY2, 0), 0) ;
|
|
double dX3 = dX2 + ( - dTenM1 - dY2) * sin( dTenA * DEGTORAD) ;
|
|
double dY3 = - dTenM1 ;
|
|
PB.AddUPoint( 3, Point3d( dX3, dY3, 0), 0) ;
|
|
PolyArc PA = PB ;
|
|
PA.Mirror( ORIG, X_AX) ;
|
|
PA.Invert( true) ;
|
|
PA.Join( PB, 3) ;
|
|
PtrOwner<ICurveComposite> pCrvTen( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvTen) || ! pCrvTen->FromPolyArc( PA))
|
|
return false ;
|
|
pCrvTen->SetExtrusion( Z_AX) ;
|
|
pCrvTen->ToGlob( frTen) ;
|
|
// lo approssimo con una spezzata
|
|
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
|
|
PolyLine PL1 ;
|
|
if ( ! pCrvTen->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL1) ||
|
|
! pCompo->FromPolyLine( PL1))
|
|
return false ;
|
|
pCompo->Close() ;
|
|
pCompo->SetExtrusion( frTen.VersZ()) ;
|
|
// Creo il contorno alto del tenone
|
|
PtrOwner<ICurveComposite> pOffs( pCrvTen->Clone()) ;
|
|
if ( IsNull( pOffs))
|
|
return false ;
|
|
double dOffs = dTenH * tan( DOVETAIL_DEF_ANG * DEGTORAD) ;
|
|
pOffs->SimpleOffset( dOffs, ICurve::OFF_EXTEND) ;
|
|
pOffs->Translate( frTen.VersZ() * dTenH) ;
|
|
// lo allungo opportunamente ad entrambi gli estremi
|
|
double dAll2 = dOffs * tan( dTenA * DEGTORAD) ;
|
|
pOffs->ExtendStartByLen( dAll2) ;
|
|
pOffs->ExtendEndByLen( dAll2) ;
|
|
// lo approssimo con una spezzata
|
|
PolyLine PL2 ;
|
|
if ( ! pOffs->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL2))
|
|
return false ;
|
|
// Creo la regione del contorno esterno
|
|
PtrOwner<ICurveComposite> pExt( CreateCurveComposite()) ;
|
|
if ( IsNull( pExt) || ! pExt->FromPolyLine( plyCut.GetPolyLine()))
|
|
return false ;
|
|
SurfFlatRegionByContours SfrExt ;
|
|
SfrExt.AddCurve( Release( pExt)) ;
|
|
PtrOwner<ISurfFlatRegion> pReg( SfrExt.GetSurf()) ;
|
|
if ( IsNull( pReg))
|
|
return false ;
|
|
// creo la regione del tenone
|
|
SurfFlatRegionByContours SfrTen ;
|
|
SfrTen.AddCurve( pCompo->Clone()) ;
|
|
PtrOwner<ISurfFlatRegion> pTen( SfrTen.GetSurf()) ;
|
|
if ( IsNull( pTen))
|
|
return false ;
|
|
// sottraggo la regione del tenone da quella esterna
|
|
if ( ! pReg->Subtract( *pTen))
|
|
return false ;
|
|
// ne deduco la superficie trimesh
|
|
PtrOwner<ISurfTriMesh> pStm( pReg->GetAuxSurf()->Clone()) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
// Creo la superficie trimesh del tenone
|
|
PtrOwner<ISurfTriMesh> pStmTen( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmTen) || ! pStmTen->CreateByTwoCurves( PL1, PL2))
|
|
return false ;
|
|
pStm->DoSewing( *pStmTen) ;
|
|
// Creo la superficie trimesh di chiusura del tenone
|
|
Point3d ptTmp ;
|
|
PolyLine PL3 ;
|
|
PL1.GetFirstPoint( ptTmp) ;
|
|
PL3.AddUPoint( 0, ptTmp) ;
|
|
PL2.GetFirstPoint( ptTmp) ;
|
|
PL3.AddUPoint( 1, ptTmp) ;
|
|
PolyLine PL4 ;
|
|
PL1.GetLastPoint( ptTmp) ;
|
|
PL4.AddUPoint( 0, ptTmp) ;
|
|
PL2.GetLastPoint( ptTmp) ;
|
|
PL4.AddUPoint( 1, ptTmp) ;
|
|
PtrOwner<ISurfTriMesh> pStmTen2( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmTen2) || ! pStmTen2->CreateByTwoCurves( PL3, PL4))
|
|
return false ;
|
|
pStm->DoSewing( *pStmTen2) ;
|
|
// Creo la superficie trimesh di testa del tenone
|
|
PL2.Close() ;
|
|
PtrOwner<ISurfTriMesh> pStmCap( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmCap) || ! pStmCap->CreateByPointCurve( ptCen, PL2))
|
|
return false ;
|
|
pStm->DoSewing( *pStmCap) ;
|
|
// eseguo trim con le facce della trave
|
|
TrimSurfTmWithBox( pStm) ;
|
|
// inserisco la superficie trimesh nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eseguo trim della curva con le facce della trave
|
|
TrimFlatCurveWithBox( pCrvTen) ;
|
|
// inserisco la curva nel DB geometrico
|
|
int nTId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvTen)) ;
|
|
if ( nTId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// identificativi di geometrie ausiliarie
|
|
SetAuxId( nId, {nTId}) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddDovetailMortise( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 14)
|
|
return false ;
|
|
// sistemo i dati
|
|
double dStartX = vdPar[0] ;
|
|
double dStartY = vdPar[1] ;
|
|
double dStartZ = - Clamp( vdPar[2], 0., 50000.) ;
|
|
Point3d ptP( dStartX, dStartY, dStartZ) ;
|
|
int nFlag = int( vdPar[3]) ;
|
|
int nPock = int( vdPar[4]) ;
|
|
double dAngle = Clamp( vdPar[5], -180.0, 180.0) ;
|
|
double dMortW = vdPar[7] ;
|
|
double dMortA = Clamp( vdPar[8], 0., 30.) ;
|
|
double dMortD = vdPar[9] ;
|
|
double dFillet = ( vdPar[10] > 10 * EPS_SMALL ? vdPar[10] / 2 : DTMILL_DEF_RAD) ;
|
|
double dStrutAng = Clamp( vdPar[6], 0.1, 179.9) ;
|
|
double dMortM1 = vdPar[12] ;
|
|
double dMortM2 = vdPar[13] ;
|
|
double dMortL = Clamp( vdPar[11] / sin( dStrutAng * DEGTORAD) - dMortM1 - dMortM2, 1., 99999.) ;
|
|
// calcolo riferimento della faccia sopra
|
|
Frame3d frMort ;
|
|
frMort.Rotate( ORIG, Z_AX, ( nGroup == 4 ? 90 + dAngle : - 90 - dAngle)) ;
|
|
frMort.ChangeOrig( ptP) ;
|
|
frMort.ToGlob( GetSideFrame( nSide)) ;
|
|
// calcolo il centro del fondo della mortasa
|
|
Point3d ptCen( 0, - dMortM1 - 0.5 * dMortL, - dMortD) ;
|
|
ptCen.ToGlob( frMort) ;
|
|
// calcolo offset tra sotto e sopra
|
|
double dOffs = dMortD * tan( DOVETAIL_DEF_ANG * DEGTORAD) ;
|
|
// Creo il contorno alto della mortasa
|
|
double dMortHW = 0.5 * dMortW ;
|
|
PolyArc PB ;
|
|
double dX0 = 0 ;
|
|
double dY0 = - dMortM1 - dMortL ;
|
|
PB.AddUPoint( 0, Point3d( dX0, dY0, 0), 0) ;
|
|
double dX1 = dMortW ;
|
|
double dY1 = dY0 ;
|
|
PB.AddUPoint( 1, Point3d( dX1, dY1, 0), 0) ;
|
|
double dX2 = dX1 + dFillet * cos( dMortA * DEGTORAD) ;
|
|
double dY2 = dY1 + dFillet * ( 1 - sin( dMortA * DEGTORAD)) ;
|
|
double dBulge2 = tan( ( ANG_RIGHT - dMortA) / 4 * DEGTORAD) ;
|
|
PB.ModifyLastBulge( dBulge2) ;
|
|
PB.AddUPoint( 2, Point3d( dX2, dY2, 0), 0) ;
|
|
double dX3 = dX2 + ( - dMortM1 - dY2) * sin( dMortA * DEGTORAD) ;
|
|
double dY3 = - dMortM1 ;
|
|
PB.AddUPoint( 3, Point3d( dX3, dY3, 0), 0) ;
|
|
double dX4, dY4 ;
|
|
if ( nPock == 0) {
|
|
double dExtraLen = GetSideWidth( nSide) ;
|
|
dX4 = dX3 + ( dExtraLen - dY3) * sin( dMortA * DEGTORAD) ;
|
|
dY4 = dExtraLen ;
|
|
}
|
|
else {
|
|
double dExtraLen = MAX_DTMORT_POCKET ;
|
|
if ( dMortA > EPS_ANG_SMALL)
|
|
dExtraLen = min( dOffs / sin( dMortA * DEGTORAD), MAX_DTMORT_POCKET) ;
|
|
dX4 = dX3 ;
|
|
dY4 = dExtraLen ;
|
|
}
|
|
PB.AddUPoint( 4, Point3d( dX4, dY4, 0), 0) ;
|
|
PolyArc PA = PB ;
|
|
PA.Mirror( ORIG, X_AX) ;
|
|
PA.Invert( true) ;
|
|
PA.Join( PB, 4) ;
|
|
PtrOwner<ICurveComposite> pCrvTop( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvTop) || ! pCrvTop->FromPolyArc( PA))
|
|
return false ;
|
|
pCrvTop->SetExtrusion( Z_AX) ;
|
|
pCrvTop->ToGlob( frMort) ;
|
|
// lo approssimo con una spezzata
|
|
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
|
|
PolyLine PL2 ;
|
|
if ( ! pCrvTop->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL2) ||
|
|
! pCompo->FromPolyLine( PL2))
|
|
return false ;
|
|
pCompo->Close() ;
|
|
pCompo->SetExtrusion( frMort.VersZ()) ;
|
|
// Creo il contorno basso della mortasa
|
|
PtrOwner<ICurveComposite> pCrvMort( pCrvTop->Clone()) ;
|
|
if ( IsNull( pCrvMort))
|
|
return false ;
|
|
pCrvMort->SimpleOffset( dOffs, ICurve::OFF_EXTEND) ;
|
|
pCrvMort->Translate( - frMort.VersZ() * dMortD) ;
|
|
// se senza tasca, lo allungo opportunamente ad entrambi gli estremi
|
|
if ( nPock == 0) {
|
|
double dAll2 = dOffs * tan( dMortA * DEGTORAD) ;
|
|
pCrvMort->ExtendStartByLen( dAll2) ;
|
|
pCrvMort->ExtendEndByLen( dAll2) ;
|
|
}
|
|
// lo approssimo con una spezzata
|
|
PolyLine PL1 ;
|
|
if ( ! pCrvMort->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL1))
|
|
return false ;
|
|
// Creo la superficie trimesh laterale della mortasa
|
|
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStm) || ! pStm->CreateByTwoCurves( PL2, PL1))
|
|
return false ;
|
|
// aggiungo la superficie trimesh di chiusura della mortasa
|
|
Point3d ptTmp ;
|
|
PolyLine PL3 ;
|
|
PL1.GetFirstPoint( ptTmp) ;
|
|
PL3.AddUPoint( 0, ptTmp) ;
|
|
PL2.GetFirstPoint( ptTmp) ;
|
|
PL3.AddUPoint( 1, ptTmp) ;
|
|
PolyLine PL4 ;
|
|
PL1.GetLastPoint( ptTmp) ;
|
|
PL4.AddUPoint( 0, ptTmp) ;
|
|
PL2.GetLastPoint( ptTmp) ;
|
|
PL4.AddUPoint( 1, ptTmp) ;
|
|
PtrOwner<ISurfTriMesh> pStmMrt( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmMrt) || ! pStmMrt->CreateByTwoCurves( PL3, PL4))
|
|
return false ;
|
|
pStm->DoSewing( *pStmMrt) ;
|
|
// aggiungo la superficie trimesh di fondo della mortasa
|
|
PL1.Close() ;
|
|
PtrOwner<ISurfTriMesh> pStmCap( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmCap) || ! pStmCap->CreateByPointCurve( ptCen, PL1))
|
|
return false ;
|
|
pStm->DoSewing( *pStmCap) ;
|
|
// eseguo trim con le facce della trave
|
|
TrimSurfTmWithBox( pStm) ;
|
|
// inserisco la superficie trimesh nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eseguo trim della curva con le facce della trave
|
|
TrimFlatCurveWithBox( pCrvMort) ;
|
|
// inserisco la curva nel DB geometrico
|
|
int nMId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvMort)) ;
|
|
if ( nMId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// identificativi di geometrie ausiliarie
|
|
SetAuxId( nId, {nMId}) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddDtMortiseFront( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 14)
|
|
return false ;
|
|
// sistemo i dati
|
|
double dStartX = vdPar[0] ;
|
|
double dStartY = vdPar[1] ;
|
|
double dStartZ = - Clamp( vdPar[2], 0., 50000.) ;
|
|
Point3d ptP( dStartX, dStartY, dStartZ) ;
|
|
int nFlag = int( vdPar[3]) ;
|
|
int nPock = int( vdPar[4]) ;
|
|
double dAngle = Clamp( vdPar[5], 0.1, 179.9) ;
|
|
double dInclination = Clamp( vdPar[6], 0.1, 179.9) ;
|
|
double dRot = Clamp( vdPar[7], 0.1, 179.9) ;
|
|
double dMortW = vdPar[8] ;
|
|
double dMortA = Clamp( vdPar[9], 0., 30.) ;
|
|
double dMortD = vdPar[10] ;
|
|
double dFillet = ( vdPar[11] > 10 * EPS_SMALL ? vdPar[11] / 2 : DTMILL_DEF_RAD) ;
|
|
double dMortM1 = ( abs( vdPar[12]) < 10 * EPS_SMALL ? 10 * EPS_SMALL : vdPar[12]) ;
|
|
double dMortM2 = ( abs( vdPar[13]) < 10 * EPS_SMALL ? 10 * EPS_SMALL : vdPar[13]) ;
|
|
// calcolo la normale alla faccia del taglio
|
|
Vector3d vtN = FromSpherical( 1, 180 + dInclination, dAngle - 90) ;
|
|
if ( nGroup == 3)
|
|
vtN.Mirror( X_AX) ;
|
|
// creo il poligono di taglio
|
|
Polygon3d plyCut ;
|
|
if ( ! CreatePolygonInBox( ptP, vtN, nSide, plyCut))
|
|
return false ;
|
|
// calcolo OCS
|
|
Frame3d frMort ;
|
|
frMort.Set( ptP, vtN, Z_AX ^ vtN) ;
|
|
frMort.Rotate( ptP, vtN, ( nGroup != 3 ? 90 - dRot : dRot - 90)) ;
|
|
frMort.ToGlob( GetSideFrame( nSide)) ;
|
|
// lunghezza della mortasa
|
|
double dThick = GetSideHeight( nSide) ;
|
|
double dCosA = frMort.VersY() * GetSideVersN( nSide) ;
|
|
double dMortL = dThick / dCosA - dMortM1 - dMortM2 ;
|
|
// calcolo il centro della mortasa
|
|
Point3d ptCen( 0, - dMortM1 - 0.5 * dMortL, -dMortD) ;
|
|
ptCen.ToGlob( frMort) ;
|
|
// calcolo offset tra sotto e sopra
|
|
double dOffs = dMortD * tan( DOVETAIL_DEF_ANG * DEGTORAD) ;
|
|
// Creo il contorno alto della mortasa
|
|
double dMortHW = 0.5 * dMortW ;
|
|
PolyArc PB ;
|
|
double dX0 = 0 ;
|
|
double dY0 = - dMortM1 - dMortL ;
|
|
PB.AddUPoint( 0, Point3d( dX0, dY0, 0), 0) ;
|
|
double dX1 = dMortW ;
|
|
double dY1 = dY0 ;
|
|
PB.AddUPoint( 1, Point3d( dX1, dY1, 0), 0) ;
|
|
double dX2 = dX1 + dFillet * cos( dMortA * DEGTORAD) ;
|
|
double dY2 = dY1 + dFillet * ( 1 - sin( dMortA * DEGTORAD)) ;
|
|
double dBulge2 = tan( ( ANG_RIGHT - dMortA) / 4 * DEGTORAD) ;
|
|
PB.ModifyLastBulge( dBulge2) ;
|
|
PB.AddUPoint( 2, Point3d( dX2, dY2, 0), 0) ;
|
|
double dX3 = dX2 + ( - dMortM1 - dY2) * sin( dMortA * DEGTORAD) ;
|
|
double dY3 = - dMortM1 ;
|
|
PB.AddUPoint( 3, Point3d( dX3, dY3, 0), 0) ;
|
|
double dX4, dY4 ;
|
|
if ( nPock == 0) {
|
|
double dExtraLen = GetSideWidth( nSide) ;
|
|
dX4 = dX3 + ( dExtraLen - dY3) * sin( dMortA * DEGTORAD) ;
|
|
dY4 = dExtraLen ;
|
|
}
|
|
else {
|
|
double dExtraLen = MAX_DTMORT_POCKET ;
|
|
if ( dMortA > EPS_ANG_SMALL)
|
|
dExtraLen = min( dOffs / sin( dMortA * DEGTORAD), MAX_DTMORT_POCKET) ;
|
|
dX4 = dX3 ;
|
|
dY4 = dExtraLen ;
|
|
}
|
|
PB.AddUPoint( 4, Point3d( dX4, dY4, 0), 0) ;
|
|
PolyArc PA = PB ;
|
|
PA.Mirror( ORIG, X_AX) ;
|
|
PA.Invert( true) ;
|
|
PA.Join( PB, 4) ;
|
|
PtrOwner<ICurveComposite> pCrvTop( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvTop) || ! pCrvTop->FromPolyArc( PA))
|
|
return false ;
|
|
pCrvTop->SetExtrusion( Z_AX) ;
|
|
pCrvTop->ToGlob( frMort) ;
|
|
// lo approssimo con una spezzata
|
|
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
|
|
PolyLine PL2 ;
|
|
if ( ! pCrvTop->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL2) ||
|
|
! pCompo->FromPolyLine( PL2))
|
|
return false ;
|
|
pCompo->Close() ;
|
|
pCompo->SetExtrusion( frMort.VersZ()) ;
|
|
// creo la regione del contorno esterno
|
|
PtrOwner<ICurveComposite> pExt( CreateCurveComposite()) ;
|
|
if ( IsNull( pExt) || ! pExt->FromPolyLine( plyCut.GetPolyLine()))
|
|
return false ;
|
|
SurfFlatRegionByContours SfrExt ;
|
|
SfrExt.AddCurve( Release( pExt)) ;
|
|
PtrOwner<ISurfFlatRegion> pReg( SfrExt.GetSurf()) ;
|
|
if ( IsNull( pReg))
|
|
return false ;
|
|
// creo la regione della mortasa
|
|
SurfFlatRegionByContours SfrMort ;
|
|
SfrMort.AddCurve( pCompo->Clone()) ;
|
|
PtrOwner<ISurfFlatRegion> pMort( SfrMort.GetSurf()) ;
|
|
if ( IsNull( pMort))
|
|
return false ;
|
|
// sottraggo la regione della mortasa da quella esterna
|
|
if ( ! pReg->Subtract( *pMort))
|
|
return false ;
|
|
// ne deduco la superficie trimesh
|
|
PtrOwner<ISurfTriMesh> pStm( pReg->GetAuxSurf()->Clone()) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
// Creo il contorno basso della mortasa
|
|
PtrOwner<ICurveComposite> pCrvMort( pCrvTop->Clone()) ;
|
|
if ( IsNull( pCrvMort))
|
|
return false ;
|
|
pCrvMort->SimpleOffset( dOffs, ICurve::OFF_EXTEND) ;
|
|
pCrvMort->Translate( - frMort.VersZ() * dMortD) ;
|
|
// se senza tasca, lo allungo opportunamente ad entrambi gli estremi
|
|
if ( nPock == 0) {
|
|
double dAll2 = dOffs * tan( dMortA * DEGTORAD) ;
|
|
pCrvMort->ExtendStartByLen( dAll2) ;
|
|
pCrvMort->ExtendEndByLen( dAll2) ;
|
|
}
|
|
// lo approssimo con una spezzata
|
|
PolyLine PL1 ;
|
|
if ( ! pCrvMort->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL1))
|
|
return false ;
|
|
// creo la superficie trimesh della mortasa
|
|
PtrOwner<ISurfTriMesh> pStmTen( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmTen) || ! pStmTen->CreateByTwoCurves( PL2, PL1))
|
|
return false ;
|
|
pStm->DoSewing( *pStmTen) ;
|
|
// aggiungo la superficie trimesh di chiusura della mortasa
|
|
Point3d ptTmp ;
|
|
PolyLine PL3 ;
|
|
PL1.GetFirstPoint( ptTmp) ;
|
|
PL3.AddUPoint( 0, ptTmp) ;
|
|
PL2.GetFirstPoint( ptTmp) ;
|
|
PL3.AddUPoint( 1, ptTmp) ;
|
|
PolyLine PL4 ;
|
|
PL1.GetLastPoint( ptTmp) ;
|
|
PL4.AddUPoint( 0, ptTmp) ;
|
|
PL2.GetLastPoint( ptTmp) ;
|
|
PL4.AddUPoint( 1, ptTmp) ;
|
|
PtrOwner<ISurfTriMesh> pStmMrt( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmMrt) || ! pStmMrt->CreateByTwoCurves( PL3, PL4))
|
|
return false ;
|
|
pStm->DoSewing( *pStmMrt) ;
|
|
// creo la superficie trimesh di fondo della mortasa
|
|
PL1.Close() ;
|
|
PtrOwner<ISurfTriMesh> pStmCap( CreateSurfTriMesh()) ;
|
|
if ( IsNull( pStmCap) || ! pStmCap->CreateByPointCurve( ptCen, PL1))
|
|
return false ;
|
|
pStm->DoSewing( *pStmCap) ;
|
|
// eseguo trim con le facce della trave
|
|
TrimSurfTmWithBox( pStm) ;
|
|
// inserisco la superficie trimesh nel DB geometrico
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// eseguo trim della curva con le facce della trave
|
|
TrimFlatCurveWithBox( pCrvMort) ;
|
|
// inserisco la curva nel DB geometrico
|
|
int nTId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvMort)) ;
|
|
if ( nTId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
// identificativi di geometrie ausiliarie
|
|
SetAuxId( nId, {nTId}) ;
|
|
// aggiusto l'outline
|
|
if ( UseProcessToTrimOutline( nId))
|
|
TrimOutline( nId) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddText( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
|
|
const INTVECTOR& vnDPar, int nSPar, 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) ;
|
|
// parametri
|
|
SetParams( nId, vnDPar, vdPar) ;
|
|
string sKey = IKEY_PAR + ToString( nSPar, 2) ;
|
|
m_pGDB->SetInfo( nId, sKey, sPar) ;
|
|
// colore per linee di marcatura e testi
|
|
m_pGDB->SetMaterial( nId, m_MarkCol) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::AddFreeContour( int nGroup, int nProc, int nSide, const string& sDes, int nProcId, const Frame3d& frRef,
|
|
const INTVECTOR& vnDPar, int nSPar, const DBLVECTOR& vdPar, const string& sPar)
|
|
{
|
|
// verifica dei parametri
|
|
if ( vdPar.size() < 10)
|
|
return false ;
|
|
// sistemo i dati
|
|
int nType = int( vdPar[5]) ;
|
|
Point3d ptP( vdPar[0], vdPar[1], vdPar[2]) ;
|
|
Point3d ptM ;
|
|
if ( nType == FreeContourEnt::ARC)
|
|
ptM.Set( vdPar[7], vdPar[8], vdPar[9]) ;
|
|
double dDepth = vdPar[3] ;
|
|
double dAng = vdPar[4] ;
|
|
int nNextId = int( vdPar[6]) ;
|
|
// se inizio del contorno...
|
|
if ( nType == FreeContourEnt::START || nType == FreeContourEnt::START_CNT0) {
|
|
// verifico che la coda sia vuota
|
|
if ( m_FcData.size() > 0) {
|
|
string sOut = " Error : found previous data in Free Contour (PId=" + ToString( nProcId) + ")" ;
|
|
LOG_ERROR( GetEExLogger(), sOut.c_str())
|
|
}
|
|
// in ogni caso la svuoto
|
|
m_FcData.clear() ;
|
|
// imposto riferimento
|
|
m_FcRef = frRef ;
|
|
// verifico spessore
|
|
if ( dDepth < EPS_SMALL)
|
|
dDepth = GetSideHeight( nSide) ;
|
|
}
|
|
// aggiusto i punti per il riferimento
|
|
ptP.ToGlob( m_FcRef) ;
|
|
ptM.ToGlob( m_FcRef) ;
|
|
// aggiungo i dati alla coda
|
|
m_FcData.emplace_back( nType, ptP, ptM, dDepth, dAng, nProcId, nNextId) ;
|
|
// se previsto un prossimo punto, continuo
|
|
if ( nNextId != 0)
|
|
return true ;
|
|
// costruisco il contorno libero
|
|
PtrOwner<ICurveComposite> pCrvCompo( CurveFromFces( m_FcData)) ;
|
|
if ( IsNull( pCrvCompo))
|
|
return false ;
|
|
m_FcData.clear() ;
|
|
// verifico se curva chiusa
|
|
bool bClosed = pCrvCompo->IsClosed() ;
|
|
// verifico se gli estremi sono sul bordo della faccia
|
|
Point3d ptStart ; pCrvCompo->GetStartPoint( ptStart) ;
|
|
Point3d ptEnd ; pCrvCompo->GetEndPoint( ptEnd) ;
|
|
bool bEndsOnCont = IsPointOnOrNearFaceContour( ptStart, true, nSide) &&
|
|
IsPointOnOrNearFaceContour( ptEnd, true, nSide) ;
|
|
// verifico se interessa tutto lo spessore della trave perpendicolarmente alla faccia
|
|
BBox3d b3Crv ; pCrvCompo->GetLocalBBox( b3Crv) ;
|
|
bool bHCross = ( ! b3Crv.IsEmpty() &&
|
|
b3Crv.GetMax().z > - EPS_SMALL &&
|
|
b3Crv.GetMin().z < - GetSideHeight( nSide) + EPS_SMALL) ;
|
|
// lo porto nel riferimento della faccia
|
|
pCrvCompo->ToGlob( GetSideFrame( nSide)) ;
|
|
// ricavo la spezzata che la approssima
|
|
PolyLine PL ;
|
|
if ( ! pCrvCompo->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL))
|
|
return false ;
|
|
// creo la superficie di estrusione corrispondente
|
|
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
|
|
Vector3d vtExtr ; pCrvCompo->GetExtrusion( vtExtr) ;
|
|
double dThick ; pCrvCompo->GetThickness( dThick) ;
|
|
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, vtExtr * dThick))
|
|
return false ;
|
|
if ( nGroup == 4)
|
|
pStm->Invert() ;
|
|
// eseguo trim con le facce della trave
|
|
TrimSurfTmWithBox( pStm) ;
|
|
// 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 ;
|
|
// inserisco la curva nel DB geometrico
|
|
int nTId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvCompo)) ;
|
|
if ( nTId == GDB_ID_NULL)
|
|
return false ;
|
|
// nome e info con tipo
|
|
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
|
|
// identificativi di geometrie ausiliarie
|
|
SetAuxId( nId, {nTId}) ;
|
|
// aggiusto l'outline se spessore come trave
|
|
if ( UseProcessToTrimOutline( nId) && bEndsOnCont && bHCross)
|
|
TrimOutline( nId) ;
|
|
|
|
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::TrimSurfTmWithBox( ISurfTriMesh* pStm)
|
|
{
|
|
// verifico esistenza superficie
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// eseguo trim con le facce della trave
|
|
for ( int i = BTL_SIDE_FRONT ; i <= BTL_SIDE_LEFT ; ++ i) {
|
|
Plane3d plFace = GetSidePlane( i) ;
|
|
pStm->Cut( plFace, true) ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::TrimFlatCurveWithBox( ICurveComposite* pCompo)
|
|
{
|
|
// verifico esistenza curva
|
|
if ( pCompo == nullptr)
|
|
return false ;
|
|
// determino il piano della curva
|
|
Plane3d plPlane ;
|
|
if ( ! pCompo->IsFlat( plPlane, 10 * EPS_SMALL))
|
|
return false ;
|
|
// determino la parte di piano (poligono) compresa nel box della trave
|
|
Polygon3d Polyg ;
|
|
if ( ! Polyg.FromPlaneTrimmedWithBox( plPlane, ORIG, ORIG + m_vtDim))
|
|
return false ;
|
|
// creo la regione corrispondente
|
|
PtrOwner<ICurveComposite> pCrv( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrv) || ! pCrv->FromPolyLine( Polyg.GetPolyLine()))
|
|
return false ;
|
|
PtrOwner<ISurfFlatRegion> pSfr( CreateSurfFlatRegion()) ;
|
|
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( Release( pCrv)))
|
|
return false ;
|
|
// calcolo la classificazione della curva rispetto alla regione
|
|
CRVCVECTOR ccClass ;
|
|
if ( ! pSfr->GetCurveClassification( *pCompo, ccClass))
|
|
return false ;
|
|
// determino gli intervalli di curva da conservare
|
|
Intervals inOk ;
|
|
for ( auto& ccOne : ccClass) {
|
|
if ( ccOne.nClass == CRVC_IN ||
|
|
ccOne.nClass == CRVC_ON_P || ccOne.nClass == CRVC_ON_M)
|
|
inOk.Add( ccOne.dParS, ccOne.dParE) ;
|
|
}
|
|
// se curva aperta
|
|
if ( ! pCompo->IsClosed()) {
|
|
// considero solo min-max degli intervalli
|
|
if ( inOk.GetCount() >= 1) {
|
|
// eseguo il taglio
|
|
double dParS, dParE ;
|
|
inOk.GetMinMax( dParS, dParE) ;
|
|
return pCompo->TrimStartEndAtParam( dParS, dParE) ;
|
|
}
|
|
}
|
|
// altrimenti curva chiusa
|
|
else {
|
|
// se c'� un solo intervallo valido
|
|
if ( inOk.GetCount() == 1) {
|
|
// eseguo il taglio
|
|
double dParS, dParE ;
|
|
inOk.GetFirst( dParS, dParE) ;
|
|
return pCompo->TrimStartEndAtParam( dParS, dParE) ;
|
|
}
|
|
// se ci sono due intervalli a cavallo del punto di giunzione
|
|
if ( inOk.GetCount() == 2) {
|
|
// recupero il dominio della curva
|
|
double dStart, dEnd ;
|
|
pCompo->GetDomain( dStart, dEnd) ;
|
|
double dParS1, dParE1 ;
|
|
inOk.GetFirst( dParS1, dParE1) ;
|
|
double dParS2, dParE2 ;
|
|
inOk.GetFirst( dParS2, dParE2) ;
|
|
if ( abs( dParS1 - dStart) < EPS_SMALL && abs( dParE2 - dEnd) < EPS_SMALL)
|
|
return pCompo->TrimStartEndAtParam( dParE1, dParS2) ;
|
|
}
|
|
}
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ICurveComposite*
|
|
BtlGeom::CurveFromFces( const FCEDEQUE& dqFce, int nStartInd)
|
|
{
|
|
// verifico validit� indice di inizio
|
|
if ( nStartInd < 0 || nStartInd >= int( dqFce.size()))
|
|
return nullptr ;
|
|
// verifico validit� tipo di inizio
|
|
if ( dqFce[nStartInd].nType != FreeContourEnt::START &&
|
|
dqFce[nStartInd].nType != FreeContourEnt::START_CNT0 &&
|
|
dqFce[nStartInd].nType != FreeContourEnt::START_CNT1)
|
|
return nullptr ;
|
|
// recupero lo spessore
|
|
double dDepth = ( dqFce[nStartInd].nType == FreeContourEnt::START ? dqFce[nStartInd].dDepth : 0) ;
|
|
// creo la curva composita
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvCompo))
|
|
return nullptr ;
|
|
// recupero le entit� free contour
|
|
for ( size_t i = nStartInd + 1 ; i < dqFce.size() ; ++ i) {
|
|
// se retta
|
|
if ( dqFce[i].nType == FreeContourEnt::LINE) {
|
|
// creo la retta
|
|
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
|
|
if ( IsNull( pCrvLine))
|
|
return nullptr ;
|
|
// setto la linea
|
|
if ( ! pCrvLine->Set( dqFce[i-1].ptP, dqFce[i].ptP))
|
|
return nullptr ;
|
|
// inserisco la linea nella curva composta
|
|
if ( ! pCrvCompo->AddCurve( ::Release( pCrvLine)))
|
|
return nullptr ;
|
|
}
|
|
// altrimenti arco
|
|
else if ( dqFce[i].nType == FreeContourEnt::ARC) {
|
|
// creo l'arco
|
|
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
|
if ( IsNull( pCrvArc))
|
|
return nullptr ;
|
|
// setto l'arco
|
|
if ( ! pCrvArc->Set3P( dqFce[i-1].ptP, dqFce[i].ptM, dqFce[i].ptP))
|
|
return nullptr ;
|
|
// inserisco l'arco nella curva composta
|
|
if ( ! pCrvCompo->AddCurve( Release( pCrvArc)))
|
|
return nullptr ;
|
|
}
|
|
// altrimenti curva terminata
|
|
else
|
|
break ;
|
|
}
|
|
// imposto versore estrusione
|
|
pCrvCompo->SetExtrusion( Z_AX) ;
|
|
// se previsto, imposto spessore
|
|
if ( dDepth > EPS_SMALL)
|
|
pCrvCompo->SetThickness( -dDepth) ;
|
|
return Release( pCrvCompo) ;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
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 ;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::SetParams( int nId, const INTVECTOR& vnDPar, const DBLVECTOR& vdPar)
|
|
{
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// elenco dei parametri
|
|
size_t nNumPar = min( vnDPar.size(), vdPar.size()) ;
|
|
for ( size_t i = 0 ; i < nNumPar ; ++ i) {
|
|
string sKey = IKEY_PAR + ToString( vnDPar[i], 2) ;
|
|
m_pGDB->SetInfo( nId, sKey, vdPar[i]) ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
bool
|
|
BtlGeom::SetAuxId( int nId, const INTVECTOR& vnAuxId)
|
|
{
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// inserisco chiave con Id di geometrie ausiliarie
|
|
m_pGDB->SetInfo( nId, IKEY_AUXID, vnAuxId) ;
|
|
return true ;
|
|
}
|