Files
EgtExchange/BtlGeomProc.cpp
T
Dario Sassi fd68e649a5 EgtExchange :
- in import BTL corretta Fessura Frontale.
2019-07-08 10:23:29 +00:00

4652 lines
194 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2017
//----------------------------------------------------------------------------
// File : BtlGeomProc.cpp Data : 15.05.17 Versione : 1.8e3
// 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.
// 15.05.17 DS Agg. import Profile Head Cambered.
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "DllMain.h"
#include "BtlGeom.h"
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EGkCurveArc.h"
#include "/EgtDev/Include/EgkArcSpecial.h"
#include "/EgtDev/Include/EGkCurveBezier.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
#include "/EgtDev/Include/EGkPolygon3d.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/ENkPolynomialRoots.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_SLOT( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 16)
#define IS_FRONT_SLOT( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 17)
#define IS_BIRDS_MOUTH( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 20)
#define IS_RIDGE_LAP( nG, nP) ( ( nGroup == 1 || nGroup == 2) && nProc == 30)
#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_CHAMFER( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 36)
#define IS_POCKET( nG, nP) ( ( nGroup == 4) && nProc == 39)
#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_MARKING( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 60)
#define IS_TEXT( nG, nP) ( ( nGroup == 4) && nProc == 61)
#define IS_SIMPLESCARF( nG, nP) ( ( nGroup == 1 || nGroup == 2) && nProc == 70)
#define IS_SCARFJOINT( nG, nP) ( ( nGroup == 1 || nGroup == 2) && nProc == 71)
#define IS_STEPJOINT( nG, nP) ( ( nGroup == 1 || nGroup == 2) && nProc == 80)
#define IS_STEPJOINTNOTCH( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 80)
#define IS_PROF_FRONT( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 100)
#define IS_PROF_HEADCONCAVE( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 101)
#define IS_PROF_HEADCONVEX( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 102)
#define IS_PROF_HEADCAMBERED( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 103)
#define IS_PROF_HEAD( nG, nP) ( ( nGroup == 3 || nGroup == 4) && nProc == 106)
#define IS_ROUND_ARCH( nG, nP) ( ( nGroup == 4) && nProc == 104)
#define IS_FREE_CONTOUR( nG, nP) ( ( nGroup == 0 || nGroup == 3 || nGroup == 4) && nProc == 250)
//----------------------------------------------------------------------------
const double COS_ALMOST_PERP = cos( 85. * DEGTORAD) ;
const double TOL_OPEN_DRILL = 1.0 ;
const double LEN_EXTRUS_AGG = 50. ;
const double BULGE_90D = tan( 90.0 / 4 * DEGTORAD) ;
//----------------------------------------------------------------------------
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 scanalatura
if ( IS_SLOT( nGroup, nProc)) {
vnDPar.reserve( 14) ; vdPar.reserve( 14) ;
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( 0) ;
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 90) ;
vnDPar.emplace_back( 8) ; vdPar.emplace_back( 90) ;
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 90) ;
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 100) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 200) ;
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 10) ;
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se scanalatura frontale
if ( IS_FRONT_SLOT( nGroup, nProc)) {
vnDPar.reserve( 9) ; vdPar.reserve( 9) ;
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) ;
vnDPar.emplace_back( 8) ; vdPar.emplace_back( 90) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 40) ;
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 40) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se tacca
if ( IS_BIRDS_MOUTH( 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( 5) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 6) ; vdPar.emplace_back( 90) ;
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 45) ;
vnDPar.emplace_back( 8) ; vdPar.emplace_back( 135) ;
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 10) ; 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( 0) ;
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se mezzo-legno di testa
if ( IS_RIDGE_LAP( 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( 6) ; vdPar.emplace_back( 90) ;
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) ;
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 intaglio
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 smusso
if ( IS_CHAMFER( nGroup, nProc)) {
vnDPar.reserve( 5) ; vdPar.reserve( 5) ;
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 4) ; vdPar.emplace_back( 1) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 1) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( GetSideLength( nSide)) ;
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se tasca
if ( IS_POCKET( 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( 4) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 6) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 8) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 90) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 20) ;
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 marcatura
if ( IS_MARKING( 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( 4) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 6) ; vdPar.emplace_back( 90) ;
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 90) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 100) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 200) ;
nSPar = 15 ; 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 giunto gerber
if ( IS_SIMPLESCARF( nGroup, nProc)) {
vnDPar.reserve( 6) ; vdPar.reserve( 6) ;
vnDPar.emplace_back( 1) ; 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) ;
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se giunto a dardo
if ( IS_SCARFJOINT( nGroup, nProc)) {
vnDPar.reserve( 9) ; vdPar.reserve( 9) ;
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 1) ;
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 0) ;
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 incastro dietro
if ( IS_STEPJOINT( nGroup, nProc)) {
vnDPar.reserve( 7) ; vdPar.reserve( 7) ;
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 4) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 45) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se incastro semplice
if ( IS_STEPJOINTNOTCH( 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( 4) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 7) ; vdPar.emplace_back( 45) ;
vnDPar.emplace_back( 10) ; vdPar.emplace_back( GetSideWidth( nSide)) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 20) ;
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 profilo frontale
if ( IS_PROF_FRONT( nGroup, nProc)) {
vnDPar.reserve( 7) ; vdPar.reserve( 7) ;
vnDPar.emplace_back( 1) ; 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) ;
vnDPar.emplace_back( 8) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 250) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 250) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se profilo concavo
if ( IS_PROF_HEADCONCAVE( nGroup, nProc)) {
vnDPar.reserve( 6) ; vdPar.reserve( 6) ;
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 120) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 20) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se profilo convesso
if ( IS_PROF_HEADCONVEX( nGroup, nProc)) {
vnDPar.reserve( 6) ; vdPar.reserve( 6) ;
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 120) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 20) ;
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 20) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se profilo caudato
if ( IS_PROF_HEADCAMBERED( nGroup, nProc)) {
vnDPar.reserve( 7) ; vdPar.reserve( 7) ;
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 500) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 40) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 60) ;
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 10) ;
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 40) ;
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 1) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se testa profilata
if ( IS_PROF_HEAD( nGroup, nProc)) {
vnDPar.reserve( 16) ; vdPar.reserve( 16) ;
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 4) ; vdPar.emplace_back( 1) ;
vnDPar.emplace_back( 9) ; vdPar.emplace_back( 0.1 * GetSideHeight( nSide)) ;
vnDPar.emplace_back( 10) ; vdPar.emplace_back( 0.1 * GetSideHeight( nSide)) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 0.1 * GetSideHeight( nSide)) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 0.3 * GetSideHeight( nSide)) ;
vnDPar.emplace_back( 13) ; vdPar.emplace_back( 0.3 * GetSideHeight( nSide)) ;
vnDPar.emplace_back( 14) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 15) ; vdPar.emplace_back( 0.1 * GetSideHeight( nSide)) ;
vnDPar.emplace_back( 16) ; vdPar.emplace_back( 0.1 * GetSideHeight( nSide)) ;
vnDPar.emplace_back( 17) ; vdPar.emplace_back( 0.1 * GetSideHeight( nSide)) ;
vnDPar.emplace_back( 18) ; vdPar.emplace_back( 0.3 * GetSideHeight( nSide)) ;
vnDPar.emplace_back( 19) ; vdPar.emplace_back( 0.3 * GetSideHeight( nSide)) ;
vnDPar.emplace_back( 20) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 21) ; vdPar.emplace_back( 0.1 * GetSideHeight( nSide)) ;
vnDPar.emplace_back( 22) ; vdPar.emplace_back( 0.1 * GetSideHeight( nSide)) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se arco
if ( IS_ROUND_ARCH( nGroup, nProc)) {
vnDPar.reserve( 3) ; vdPar.reserve( 3) ;
vnDPar.emplace_back( 1) ; vdPar.emplace_back( 0) ;
vnDPar.emplace_back( 11) ; vdPar.emplace_back( 30) ;
vnDPar.emplace_back( 12) ; vdPar.emplace_back( 500) ;
nSPar = 0 ; sPar.empty() ;
return true ;
}
// se contorno libero
if ( IS_FREE_CONTOUR( nGroup, nProc)) {
vnDPar.reserve( 11) ; vdPar.reserve( 11) ;
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( 7) ; 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, const STRVECTOR& vsUAtt, int nLine)
{
// salvo numero di linea del file in cui definito il processo
m_nBtlLine = nLine ;
// se taglio
if ( IS_CUT( nGroup, nProc))
return AddCut( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se taglio longitudinale
if ( IS_LONGIT_CUT( nGroup, nProc))
return AddLongitCut( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se doppio taglio
if ( IS_DOUBLE_CUT( nGroup, nProc))
return AddDoubleCut( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se doppio taglio longitudinale
if ( IS_RIDGEVALLEY_CUT( nGroup, nProc))
return AddRidgeValleyCut( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se scanalatura
if ( IS_SLOT( nGroup, nProc))
return AddSlot( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se scanalatura frontale
if ( IS_FRONT_SLOT( nGroup, nProc))
return AddFrontSlot( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se tacca
if ( IS_BIRDS_MOUTH( nGroup, nProc))
return AddBirdsMouth( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se mezzo-legno di testa
if ( IS_RIDGE_LAP( nGroup, nProc))
return AddRidgeLap( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se mezzo-legno
if ( IS_LAP_JOINT( nGroup, nProc))
return AddLapJoint( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se intaglio
if ( IS_NOTCH( nGroup, nProc))
return AddNotch( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se taglio per rivestimento
if ( IS_SEATHING_CUT( nGroup, nProc))
return AddSeathingCut( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se smusso
if ( IS_CHAMFER( nGroup, nProc))
return AddChamfer( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se tasca
if ( IS_POCKET( nGroup, nProc))
return AddPocket( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se foratura
if ( IS_DRILL( nGroup, nProc))
return AddDrill( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se tenone
if ( IS_TENON( nGroup, nProc))
return AddTenon( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se mortasa
if ( IS_MORTISE( nGroup, nProc))
return AddMortise( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se mortasa sul fronte
if ( IS_MORTISE_FRONT( nGroup, nProc))
return AddMortiseFront( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se avanzamento tenone
if ( IS_HOUSE( nGroup, nProc)) {
nGroup = ( nGroup == 3 ? 1 : 2) ;
return AddTenon( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
}
// se avanzamento mortasa
if ( IS_HOUSE_MORTISE( nGroup, nProc))
return AddMortise( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se tenone a coda di rondine
if ( IS_DOVETAIL_TENON( nGroup, nProc))
return AddDovetailTenon( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se mortasa a coda di rondine
if ( IS_DOVETAIL_MORTISE( nGroup, nProc))
return AddDovetailMortise( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se mortasa a coda di rondine sul fronte
if ( IS_DTMORTISE_FRONT( nGroup, nProc))
return AddDtMortiseFront( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se marcatura
if ( IS_MARKING( nGroup, nProc))
return AddMarking( nGroup, nProc, nSide, sDes, nProcId, vnDPar, nSPar, vdPar, sPar, vsUAtt) ;
// se testo
if ( IS_TEXT( nGroup, nProc))
return AddText( nGroup, nProc, nSide, sDes, nProcId, vnDPar, nSPar, vdPar, sPar, vsUAtt) ;
// se giunto gerber
if ( IS_SIMPLESCARF( nGroup, nProc))
return AddSimpleScarf( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se giunto a dardo
if ( IS_SCARFJOINT( nGroup, nProc))
return AddScarfJoint( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// incastro dietro
if ( IS_STEPJOINT( nGroup, nProc))
return AddStepJoint( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se incastro semplice
if ( IS_STEPJOINTNOTCH( nGroup, nProc))
return AddStepJointNotch( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se profilo frontale
if ( IS_PROF_FRONT( nGroup, nProc))
return AddProfileFront( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se profilo concavo
if ( IS_PROF_HEADCONCAVE( nGroup, nProc))
return AddProfileHeadCoCo( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se profilo convesso
if ( IS_PROF_HEADCONVEX( nGroup, nProc))
return AddProfileHeadCoCo( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se profilo caudato
if ( IS_PROF_HEADCAMBERED( nGroup, nProc))
return AddProfileHeadCambered( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se testa profilata
if ( IS_PROF_HEAD( nGroup, nProc))
return AddProfileHead( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se arco
if ( IS_ROUND_ARCH( nGroup, nProc))
return AddRoundArch( nGroup, nProc, nSide, sDes, nProcId, vnDPar, vdPar, vsUAtt) ;
// se contorno libero
if ( IS_FREE_CONTOUR( nGroup, nProc))
return AddFreeContour( nGroup, nProc, nSide, sDes, nProcId, frRef, vnDPar, nSPar, vdPar, sPar, vsUAtt) ;
return false ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddCut( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// 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 ;
if ( plyCut.GetSideCount() < 3) {
string sOut = " Warning : Empty Process (" + ToString( nGroup) + "-" + ToString( nProc, 3) + "-" + ToString( nSide) +
") on line " + ToString( m_nBtlLine) ;
LOG_WARN( GetEExLogger(), sOut.c_str())
return true ;
}
// 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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// 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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// 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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// 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], -50000., 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, vsUAtt) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddSlot( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 14)
return false ;
// sistemo i dati
Point3d ptP( vdPar[0], vdPar[1], -vdPar[2]) ; // P01, P02, P03
int nFlag = lround( vdPar[3]) ; // P04
double dAngle = Clamp( vdPar[4], -90., 90.9) ; // P06
double dInclination = Clamp( vdPar[5], 0.1, 179.9) ; // P07
double dIntAngRef = Clamp( vdPar[6], 0.1, 179.9) ; // P08
double dIntAngOpp = Clamp( vdPar[7], 0.1, 179.9) ; // P09
double dAddAngOpp = Clamp( vdPar[8], 0.1-dIntAngOpp, 179.9-dIntAngOpp) ; // P10
double dDepth = Clamp( vdPar[9], 1., 50000.) ; // P11
double dLength = Clamp( vdPar[10], 1., 100000.) ; // P12
double dThick = Clamp( vdPar[11], 1., 50000.) ; // P13
double dDispEntRef = Clamp( vdPar[12], 0., 50000.) ; // P14
double dDispEntOpp = Clamp( vdPar[13], 0., 50000.) ; // P15
// costruzione delle normali delle facce
double dAngEff = ( nGroup == 4 ? dAngle : ANG_STRAIGHT - dAngle) ;
double dInclEff = ( nGroup == 4 ? dInclination : ANG_STRAIGHT - dInclination) ;
Vector3d vtN1 = Z_AX ;
vtN1.Rotate( Y_AX, dIntAngRef) ;
Vector3d vtN3 = - vtN1 ;
vtN3.Rotate( Y_AX, dAddAngOpp) ;
Vector3d vtNf = vtN1 ;
vtNf.Rotate( Y_AX, - dIntAngOpp) ;
vtNf.Rotate( X_AX, dInclEff - 90) ;
Vector3d vtN2 = - Z_AX ;
vtN2.Rotate( X_AX, dInclEff) ;
Vector3d vtN4 = - vtN2 ;
vtN1.Rotate( Z_AX, dAngEff) ;
vtN2.Rotate( Z_AX, dAngEff) ;
vtN3.Rotate( Z_AX, dAngEff) ;
vtN4.Rotate( Z_AX, dAngEff) ;
vtNf.Rotate( Z_AX, dAngEff) ;
// costruzione dei vettori edge faccia 1
Vector3d vtEv = vtN1 ^ vtN2 ;
vtEv.Normalize() ;
Vector3d vtEo = vtN1 ^ vtNf ;
vtEo.Normalize() ;
double dCoeff = vtEv.z ;
// se caso frontale
if ( abs( ptP.z) > EPS_SMALL) {
double dRotAng = ( nGroup == 4 ? - ANG_RIGHT : ANG_RIGHT) ;
vtN1.Rotate( Y_AX, dRotAng) ;
vtN2.Rotate( Y_AX, dRotAng) ;
vtN3.Rotate( Y_AX, dRotAng) ;
vtN4.Rotate( Y_AX, dRotAng) ;
vtNf.Rotate( Y_AX, dRotAng) ;
vtEv.Rotate( Y_AX, dRotAng) ;
vtEo.Rotate( Y_AX, dRotAng) ;
}
// calcolo del punto sul fondo
Point3d ptB = ptP - vtEv * ( dDepth / dCoeff) ;
// facce
Polygon3d plyFaceF ;
if ( ! CreatePolygonInBox( ptB, vtNf, nSide, plyFaceF))
return false ;
Polygon3d plyFace1 ;
if ( ! CreatePolygonInBox( ptB, vtN1, nSide, plyFace1))
return false ;
Polygon3d plyFace2 ;
if ( ! CreatePolygonInBox( ptB + vtEo * dThick / 2, vtN2, nSide, plyFace2))
return false ;
Polygon3d plyFace3 ;
if ( ! CreatePolygonInBox( ptB + vtN1 * dLength, vtN3, nSide, plyFace3))
return false ;
Polygon3d plyFace4 ;
if ( ! CreatePolygonInBox( ptB - vtEo * dThick / 2, vtN4, nSide, plyFace4))
return false ;
// trimmo tra loro le facce
if ( ! TrimPolygons( plyFaceF, plyFace1, false, false) ||
! TrimPolygons( plyFaceF, plyFace2, false, false) ||
! TrimPolygons( plyFaceF, plyFace3, false, false) ||
! TrimPolygons( plyFaceF, plyFace4, false, false))
return false ;
if ( ! TrimPolygons( plyFace1, plyFace2, false, false) ||
! TrimPolygons( plyFace2, plyFace3, false, false) ||
! TrimPolygons( plyFace3, plyFace4, false, false) ||
! TrimPolygons( plyFace4, plyFace1, false, false))
return false ;
// creo la trimesh dalle facce
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm))
return false ;
if ( ! DoSewing( pStm, plyFaceF) || ! DoSewing( pStm, plyFace1) ||
! DoSewing( pStm, plyFace2) || ! DoSewing( pStm, plyFace3) ||
! DoSewing( pStm, plyFace4))
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, vsUAtt) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddFrontSlot( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 9)
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) ;
double dRot = Clamp( vdPar[5], 0., 360.) ;
double dMortD = Clamp( vdPar[6], 0., 50000.) ;
double dMortL = Clamp( vdPar[7], 0., 50000.) ;
double dMortW = Clamp( vdPar[8], 0., 50000.) ;
// 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)) ;
// creo il contorno della mortasa
double dMortHL = 0.5 * dMortL ;
double dMortHW = 0.5 * dMortW ;
PolyLine PL ;
PL.AddUPoint( 0, Point3d( - dMortHW, dMortHL, 0)) ;
PL.AddUPoint( 1, Point3d( - dMortHW, - dMortHL, 0)) ;
PL.AddUPoint( 2, Point3d( dMortHW, - dMortHL, 0)) ;
PL.AddUPoint( 3, Point3d( dMortHW, dMortHL, 0)) ;
PL.Close() ;
PL.ToGlob( frMort) ;
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL))
return false ;
pCompo->SetExtrusion( frMort.VersZ()) ;
// definisco la superficie di taglio
PtrOwner<ISurfTriMesh> pCut ;
// 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
pCut.Set( pReg->GetAuxSurf()->Clone()) ;
if ( IsNull( pCut))
return false ;
}
// definisco la superficie della mortasa
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
// creo la superficie trimesh laterale della mortasa
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, - frMort.VersZ() * dMortD))
return false ;
// creo la superficie trimesh di fondo della mortasa
PtrOwner<ISurfTriMesh> pStmCap( CreateSurfTriMesh()) ;
if ( IsNull( pStmCap) || ! pStmCap->CreateByFlatContour( PL))
return false ;
pStmCap->Translate( - frMort.VersZ() * dMortD) ;
pStm->DoSewing( *pStmCap) ;
// eseguo trim con le facce della trave
TrimSurfTmWithBox( pStm) ;
// superficie totale per aggiustare l'outline
PtrOwner<ISurfTriMesh> pTrim ;
if ( ! IsNull( pCut)) {
pTrim.Set( pCut->Clone()) ;
pTrim->DoSewing( *pStm) ;
}
else
pTrim.Set( pStm->Clone()) ;
// inserisco la superficie trimesh della mortasa nel DB geometrico
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pStm)) ;
if ( nId == GDB_ID_NULL)
return false ;
// se presente, inserisco la superficie trimesh del taglio nel DB geometrico
int nCutId = GDB_ID_NULL ;
if ( ! IsNull( pCut)) {
nCutId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCut)) ;
if ( nCutId == GDB_ID_NULL)
return false ;
}
// colore semitrasparente
SetAlpha( nCutId, 80) ;
// nome e info con tipo
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
// parametri
SetParams( nId, vnDPar, vdPar, vsUAtt) ;
// identificativi di geometrie ausiliarie
if ( nCutId != GDB_ID_NULL)
SetAuxId( nId, {nCutId}) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( pTrim) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddBirdsMouth( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 13)
return false ;
// sistemo i dati
Point3d ptO( vdPar[0], vdPar[1], 0) ; // P01, P02
int nFlag = lround( vdPar[2]) ; // P05
double dAngle = Clamp( vdPar[3], 0.1, 179.) ; // P06
double dInclin1 = Clamp( vdPar[4], 0., 180.) ; // P07
double dInclin2 = Clamp( vdPar[5], 0., 180.) ; // P08
double dCutAng = Clamp( vdPar[6], 0., 179.) ; // P09
double dCutIncl = Clamp( vdPar[7], 0., 179.) ; // P10
double dDepth1 = Clamp( vdPar[8], 0., 50000.) ; // P11
double dDepth2 = Clamp( vdPar[9], 0., 50000.) ; // P12
double dWidth = Clamp( vdPar[10], 0., 50000.) ; // P13
if ( dWidth < EPS_SMALL)
dWidth = GetSideWidth( nSide) - ptO.y ;
double dHeightCnt = Clamp( vdPar[11], 0., 50000.) ; // P14
double dWidthCnt = Clamp( vdPar[12], 0., 50000.) ; // P15
// punti estremi dell'intersezione tra le facce principali
Point3d ptP = ptO - Z_AX * dDepth1 ;
Vector3d vtD = FromPolar( 1, dAngle) ;
if ( nGroup == 4)
vtD.Mirror( X_AX) ;
double dDist = dWidth / abs( vtD.y) ;
Point3d ptQ = ptO + vtD * dDist - Z_AX * dDepth2 ;
// calcolo delle normali due facce principali
Vector3d vtR = ptQ - ptP ;
vtR.Normalize() ;
Vector3d vtN1 = ( vtR ^ Z_AX) ^ vtR ;
vtN1.Normalize() ;
vtN1.Rotate( vtR, ( nGroup == 3 ? dInclin1 : - dInclin1)) ;
Vector3d vtN2 = - ( vtR ^ Z_AX) ^ vtR ;
vtN2.Rotate( vtR, ( nGroup == 3 ? dInclin2 : - dInclin2)) ;
vtN2.Normalize() ;
// creo il poligono della prima faccia
Polygon3d plyFace1 ;
if ( ! CreatePolygonInBox( ptP, vtN1, nSide, plyFace1))
return false ;
// creo il poligono della seconda faccia
Polygon3d plyFace2 ;
if ( ! CreatePolygonInBox( ptP, vtN2, nSide, plyFace2))
return false ;
// trimmo tra loro le due facce
if ( ! TrimPolygons( plyFace1, plyFace2, false, false))
return false ;
// eventuale terza faccia (offset della seconda) di contenimento della prima
Polygon3d plyFace3 ;
if ( dWidthCnt > EPS_SMALL && plyFace1.GetSideCount() > 0) {
// la creo come offset della seconda
Point3d ptT = ptP + vtN2 * dWidthCnt ;
if ( ! CreatePolygonInBox( ptT, - vtN2, nSide, plyFace3))
return false ;
// trimmo tra loro prima e terza
if ( ! TrimPolygons( plyFace1, plyFace3, false, false))
return false ;
}
// eventuale quarta faccia (offset della prima) di contenimento della seconda
Polygon3d plyFace4 ;
if ( dHeightCnt > EPS_SMALL && plyFace2.GetSideCount() > 0) {
// la creo come offset della prima
Point3d ptT = ptP + vtN1 * dHeightCnt ;
if ( ! CreatePolygonInBox( ptT, - vtN1, nSide, plyFace4))
return false ;
// trimmo tra loro seconda e quarta
if ( ! TrimPolygons( plyFace2, plyFace4, false, false))
return false ;
}
// eventuale quinta faccia (limite di fronte)
Polygon3d plyFace5 ;
if ( abs( ptO.y) > EPS_SMALL) {
// imposto la normale per faccia anti-parallela al fronte
Vector3d vtN5 = Y_AX ;
// se caso generico
if ( dCutAng > EPS_ANG_SMALL && dCutIncl > EPS_ANG_SMALL) {
Vector3d vtRe = vtR ;
vtRe.Rotate( vtN1, (( nGroup == 3) ? dCutAng : -dCutAng)) ;
vtN5 = -vtN1 ;
vtN5.Rotate( vtRe, (( nGroup == 3) ? -dCutIncl : dCutIncl)) ;
}
// calcolo la faccia
if ( ! CreatePolygonInBox( ptP, vtN5, nSide, plyFace5))
return false ;
// trimmo con le altre
if ( ! TrimPolygons( plyFace5, plyFace1, false, false) ||
! TrimPolygons( plyFace5, plyFace2, false, false) ||
! TrimPolygons( plyFace5, plyFace3, false, false) ||
! TrimPolygons( plyFace5, plyFace4, false, false))
return false ;
}
// eventuale sesta faccia (limite dietro)
Polygon3d plyFace6 ;
if ( abs( ptO.y + dWidth - GetSideWidth( nSide)) > EPS_SMALL) {
// imposto la normale per faccia parallela al fronte
Vector3d vtN6 = -Y_AX ;
// se caso generico
if ( dCutAng > EPS_ANG_SMALL && dCutIncl > EPS_ANG_SMALL) {
// se esiste la faccia 5, opposta
if ( plyFace5.GetSideCount() > 0)
vtN6 = - plyFace5.GetVersN() ;
// altrimenti la calcolo
else {
Vector3d vtRe = - vtR ;
vtRe.Rotate( vtN1, (( nGroup == 3) ? -dCutAng : dCutAng)) ;
vtN6 = -vtN1 ;
vtN6.Rotate( vtRe, (( nGroup == 3) ? dCutIncl : -dCutIncl)) ;
}
}
// calcolo la faccia
if ( ! CreatePolygonInBox( ptQ, vtN6, nSide, plyFace6))
return false ;
// trimmo con le altre
if ( ! TrimPolygons( plyFace6, plyFace1, false, false) ||
! TrimPolygons( plyFace6, plyFace2, false, false) ||
! TrimPolygons( plyFace6, plyFace3, false, false) ||
! TrimPolygons( plyFace6, plyFace4, false, false))
return false ;
}
// creo la trimesh dalle facce
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm))
return false ;
if ( ! DoSewing( pStm, plyFace1) || ! DoSewing( pStm, plyFace2) ||
! DoSewing( pStm, plyFace3) || ! DoSewing( pStm, plyFace4) ||
! DoSewing( pStm, plyFace5) || ! DoSewing( pStm, plyFace6))
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, vsUAtt) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddRidgeLap( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 6)
return false ;
// sistemo i dati
double dStartX = vdPar[0] ; // P01
int nFlag = lround( vdPar[1]) ; // P02
double dAngle = Clamp( vdPar[2], 0.1, 179.9) ; // P06
double dDepth = Clamp( vdPar[3], 1., 50000.) ; // P11
double dWidth = Clamp( vdPar[4], 1., 50000.) ; // P12
double dHoDiam = Clamp( vdPar[5], 0., 1000.) ; // P13
Point3d ptP( dStartX, (( nFlag == 0) ? 0 : GetSideWidth( nSide)), - dDepth) ;
// calcolo la normale alla prima faccia del taglio
Vector3d vtN = FromPolar( 1, 90 - dAngle) ;
if ( nGroup == 2)
vtN.Mirror( X_AX) ;
if ( nFlag != 0)
vtN.Mirror( Y_AX) ;
// creo il primo poligono di taglio
Polygon3d plyFace1 ;
if ( ! CreatePolygonInBox( ptP, vtN, nSide, plyFace1))
return false ;
// creo il secondo poligono di taglio
Polygon3d plyFace2 ;
if ( ! CreatePolygonInBox( ptP, Z_AX, nSide, plyFace2))
return false ;
// creo il terzo poligono di taglio
Polygon3d plyFace3 ;
if ( ! CreatePolygonInBox( ptP - vtN * dWidth, vtN, nSide, plyFace3))
return false ;
// trim tra queste facce
if ( ! TrimPolygons( plyFace1, plyFace2, true, false) ||
! TrimPolygons( plyFace2, plyFace3, false, false))
return false ;
// creo la trimesh dalle facce
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm))
return false ;
if ( ! DoSewing( pStm, plyFace1) ||
! DoSewing( pStm, plyFace2) ||
! DoSewing( pStm, plyFace3))
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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 13)
return false ;
// sistemo i dati
double dStartX = vdPar[0] ; // P01
double dStartY = vdPar[1] ; // P02
double dStartZ = - Clamp( vdPar[2], 0., 50000.) ; // P03
int nFlag = lround( vdPar[3]) ; // P04
double dAngle = Clamp( vdPar[4], 0.1, 179.9) ; // P06
double dInclination = Clamp( vdPar[5], 0.1, 179.9) ; // P07
double dSlope = Clamp( vdPar[6], -89.9, 89.9) ; // P08
double dLeadAngle = Clamp( vdPar[7], 0., 179.9) ; // P09
double dLeadIncl = Clamp( vdPar[8], 0., 179.9) ; // P10
double dDepth = vdPar[9] ; // P11
double dLength = Clamp( vdPar[10], 1., 99999.) ; // P12
double dChAng = Clamp( vdPar[11], 0., 89.) ; // P13
double dWidth = ( ( vdPar[12] > EPS_SMALL) ? vdPar[12] : GetSideWidth( nSide) - dStartY) ; // P14
Point3d ptP( dStartX, dStartY, dStartZ) ;
//// disabilito nFlag
// nFlag = 0 ;
// 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)) {
// senza angolo di smusso su sola faccia inizio (condizioni da manuale BTL)
if ( dStartZ < - EPS_SMALL || dLeadAngle > EPS_ANG_SMALL || dLeadIncl > EPS_ANG_SMALL || dChAng < EPS_ANG_SMALL ||
abs( dInclination - 90.) > EPS_ANG_SMALL || abs( dSlope) > EPS_ANG_SMALL) {
if ( ! CreatePolygonInBox( ptP, vtN1, nSide, plyStart))
return false ;
}
// con angolo di smusso
else {
Vector3d vtNr = vtN1 ;
if ( dChAng > EPS_ANG_SMALL) {
Vector3d vtR = FromPolar( 1, dAngle) ;
if ( nGroup == 4)
vtR.Mirror( X_AX) ;
vtNr.Rotate( vtR, (( nGroup == 3) ? dChAng : -dChAng)) ;
}
Point3d ptQ = ptP - Z_AX * dDepth ;
if ( ! CreatePolygonInBox( ptQ, vtNr, 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 ;
}
// verifica di queste facce
VerifyPolygon( plyStart) ;
VerifyPolygon( plyEnd) ;
VerifyPolygon( plyFront) ;
VerifyPolygon( plyBack) ;
// 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 ;
VerifyPolygon( plyTop) ;
}
// 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 ;
VerifyPolygon( plyBottom) ;
}
// 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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 6)
return false ;
// sistemo i dati
int nFlag = lround( vdPar[2]) ; // P04
double dDepth = Clamp( vdPar[3], 0., 50000.) ; // P11
double dLength = Clamp( vdPar[4], 1., 99999.) ; // P12
double dWidth = Clamp( vdPar[5], 1., 50000.) ; // P13
Point3d ptP( vdPar[0], vdPar[1] - 0.5 * dWidth, 0.) ; // P01, P02
// 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 ;
// faccia di fondo
Polygon3d plyBottom ;
if ( ! CreatePolygonInBox( ptP - dDepth * Z_AX, Z_AX, nSide, plyBottom))
return false ;
// verifico tra loro le facce
if ( ! VerifyPolygonWithPolygons( plyBottom, plyStart, plyEnd, plyFront, plyBack, false))
plyBottom.Clear() ;
if ( ! VerifyPolygonWithPolygons( plyStart, plyFront, plyBottom, plyBack, false))
plyStart.Clear() ;
if ( ! VerifyPolygonWithPolygons( plyEnd, plyFront, plyBottom, plyBack, false))
plyEnd.Clear() ;
if ( ! VerifyPolygonWithPolygons( plyFront, plyStart, plyBottom, plyEnd, false))
plyFront.Clear() ;
if ( ! VerifyPolygonWithPolygons( plyBack, plyStart, plyBottom, plyEnd, false))
plyBack.Clear() ;
// trim tra le facce
if ( ! TrimPolygons( plyBottom, plyStart, false, false))
return false ;
if ( ! TrimPolygons( plyBottom, plyEnd, false, false))
return false ;
if ( ! TrimPolygons( plyBottom, plyFront, false, false))
return false ;
if ( ! TrimPolygons( plyBottom, plyBack, false, false))
return false ;
if ( ! TrimPolygons( plyStart, plyFront, false, false))
return false ;
if ( ! TrimPolygons( plyStart, plyBack, false, false))
return false ;
if ( ! TrimPolygons( plyEnd, plyFront, false, false))
return false ;
if ( ! TrimPolygons( plyEnd, 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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// 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, vsUAtt) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddChamfer( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 5)
return false ;
// sistemo i dati
double dPos = vdPar[0] ; // P01
int nFlag = lround( vdPar[1]) ; // P04
double dDepth = Clamp( vdPar[2], 1., 100.) ; // P11
double dLen = Clamp( vdPar[3], 0., 100000.) ; // P12
int nExit = lround( vdPar[4]) ; // P15
// determino posizione di inizio e fine
double dStart = ( nGroup == 4 ? dPos : dPos - dLen) ;
double dEnd = ( nGroup == 4 ? dPos + dLen : dLen) ;
if ( dLen < EPS_SMALL) {
dStart = 0 ;
dEnd = GetSideLength( nSide) ;
}
// creo gli smussi richiesti
int nEnable[4] = { 1, 2, 4, 8} ;
for ( int i = 1 ; i <= 4 ; ++ i) {
// se smusso non richiesto, vado oltre
if ( ( nFlag & nEnable[i-1]) == 0)
continue ;
// assegno il fianco di costruzione effettivo
int nRefSide = i ;
// calcolo il piano di fondo
Vector3d vtN( 0, - SQRT1_2, SQRT1_2) ;
Polygon3d plyBottom ;
if ( ! CreatePolygonInBox( ORIG - vtN * dDepth * SQRT1_2, vtN, nRefSide, plyBottom))
return false ;
// calcolo il piano di inizio
Vector3d vtNs = X_AX ;
if ( nExit == 1) {
vtNs.Rotate( Y_AX, -45) ;
vtNs.Rotate( X_AX, 45) ;
}
Polygon3d plyStart ;
if ( ! CreatePolygonInBox( Point3d(dStart, 0, 0), vtNs, nRefSide, plyStart))
return false ;
// calcolo il piano di fine
Vector3d vtNe = -X_AX ;
if ( nExit == 1) {
vtNe.Rotate( Y_AX, 45) ;
vtNe.Rotate( X_AX, 45) ;
}
Polygon3d plyEnd ;
if ( ! CreatePolygonInBox( Point3d(dEnd, 0, 0), vtNe, nRefSide, plyEnd))
return false ;
// eseguo trim tra le facce
if ( ! TrimPolygons( plyBottom, plyStart, false, false) ||
! TrimPolygons( plyBottom, plyEnd, false, false))
return false ;
// creo la trimesh con questi contorni
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm))
return false ;
DoSewing( pStm, plyBottom) ;
DoSewing( pStm, plyStart) ;
DoSewing( pStm, plyEnd) ;
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
string sMyDes = ToString( i) + "-" + sDes ;
SetNameAndInfo( nId, nGroup, nProc, nSide, sMyDes, nProcId) ;
// parametri
DBLVECTOR vdMyPar = vdPar ;
vdMyPar[1] = nEnable[i-1] ;
SetParams( nId, vnDPar, vdMyPar, vsUAtt) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddPocket( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 10)
return false ;
// sistemo i dati
Point3d ptP( vdPar[0], vdPar[1], - vdPar[7]) ; // P01, P02, P11
int nFlag = lround( vdPar[2]) ; // P04
double dAngle = Clamp( vdPar[3], -179.9, 179.9) ; // P06
double dIncl = Clamp( vdPar[4], -179.9, 179.9) ; // P07
double dSlope = Clamp( vdPar[5], -179.9, 179.9) ; // P08
double dIntAng = Clamp( vdPar[6], 0.1, 179.9) ; // P10
double dLen = Clamp( vdPar[8], 0., 50000.) ; // P12
double dWidth = Clamp( vdPar[9], 0., 50000.) ; // P13
// riferimento rototraslato
Frame3d frRef( ptP) ;
frRef.Rotate( ptP, frRef.VersZ(), dAngle) ;
frRef.Rotate( ptP, frRef.VersY(), dIncl) ;
frRef.Rotate( ptP, frRef.VersX(), dSlope) ;
// creo il poligono della faccia di fondo
Vector3d vtN1 = frRef.VersZ() ;
Polygon3d plyFace1 ;
if ( ! CreatePolygonInBox( ptP, vtN1, nSide, plyFace1))
return false ;
// creo il poligono della faccia sinistra
Vector3d vtN2 = frRef.VersX() ;
vtN2.Rotate( frRef.VersZ(), dIntAng - 90) ;
Polygon3d plyFace2 ;
if ( ! CreatePolygonInBox( ptP, vtN2, nSide, plyFace2))
return false ;
// creo il poligono della faccia destra
Polygon3d plyFace4 ;
if ( ! CreatePolygonInBox( ptP + vtN2 * dLen, - vtN2, nSide, plyFace4))
return false ;
// creo il poligono della faccia davanti
Vector3d vtN3 = frRef.VersY() ;
Polygon3d plyFace3 ;
if ( ! CreatePolygonInBox( ptP, vtN3, nSide, plyFace3))
return false ;
// creo il poligono della faccia dietro
Polygon3d plyFace5 ;
if ( ! CreatePolygonInBox( ptP + vtN3 * dWidth, - vtN3, nSide, plyFace5))
return false ;
// verifico tra loro le facce
if ( ! VerifyPolygonWithPolygons( plyFace1, plyFace2, plyFace3, plyFace4, plyFace5, false))
plyFace1.Clear() ;
if ( ! VerifyPolygonWithPolygons( plyFace2, plyFace3, plyFace1, plyFace5, false))
plyFace2.Clear() ;
if ( ! VerifyPolygonWithPolygons( plyFace3, plyFace2, plyFace1, plyFace4, false))
plyFace3.Clear() ;
if ( ! VerifyPolygonWithPolygons( plyFace4, plyFace3, plyFace1, plyFace5, false))
plyFace4.Clear() ;
if ( ! VerifyPolygonWithPolygons( plyFace5, plyFace2, plyFace1, plyFace4, false))
plyFace5.Clear() ;
// trimmo tra loro le facce
if ( ! TrimPolygons( plyFace1, plyFace2, false, false) ||
! TrimPolygons( plyFace1, plyFace3, false, false) ||
! TrimPolygons( plyFace1, plyFace4, false, false) ||
! TrimPolygons( plyFace1, plyFace5, false, false) ||
! TrimPolygons( plyFace2, plyFace3, false, false) ||
! TrimPolygons( plyFace3, plyFace4, false, false) ||
! TrimPolygons( plyFace4, plyFace5, false, false) ||
! TrimPolygons( plyFace5, plyFace2, false, false))
return false ;
// creo la trimesh con questi contorni
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm))
return false ;
DoSewing( pStm, plyFace1) ;
DoSewing( pStm, plyFace2) ;
DoSewing( pStm, plyFace3) ;
DoSewing( pStm, plyFace4) ;
DoSewing( pStm, plyFace5) ;
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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 7)
return false ;
// sistemo i dati
Point3d ptP( vdPar[0], vdPar[1], - vdPar[2]) ; // P01, P02, P03
double dAngHor = Clamp( vdPar[3], 0., 360.) ; // P06
double dAngVert = Clamp( abs( vdPar[4]), 1., 179.) ; // P07
double dDepth = vdPar[5] / sin( dAngVert * DEGTORAD) ; // P11
double dRad = vdPar[6] / 2 ; // P12
// verifica del raggio
if ( dRad < 0.5)
return false ;
// 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) ;
}
}
// porto i dati in globale
Frame3d frRef = GetSideFrame( nSide) ;
ptP.ToGlob( frRef) ;
vtN.ToGlob( frRef) ;
// determino i punti iniziale e finale
Point3d ptStart = ptP ;
Point3d ptEnd = ptP - vtN * dDepth ;
// limito i punti, tenendo conto del raggio
if ( ! TrimSegmentWithBox( ptStart, ptEnd, dRad)) {
string sOut = " Warning : Empty Process (" + ToString( nGroup) + "-" + ToString( nProc, 3) + "-" + ToString( nSide) +
") on line " + ToString( m_nBtlLine) ;
LOG_WARN( GetEExLogger(), sOut.c_str())
return true ;
}
dDepth = ( ptStart - ptEnd) * vtN ;
// creo la circonferenza
PtrOwner<ICurveArc> pArc( CreateCurveArc()) ;
if ( IsNull( pArc))
return false ;
// assegno i dati
if ( ! pArc->Set( ptStart, vtN, dRad))
return false ;
pArc->SetExtrusion( vtN) ;
pArc->SetThickness( - dDepth) ;
// verifico se inizio su faccia (o fuori)
int nStartFace = 0 ;
double dSinStart = 0 ;
for ( int i = BTL_SIDE_FRONT ; i <= BTL_SIDE_LEFT ; ++ i) {
Plane3d plSide = GetSidePlane( i) ;
if ( DistPointPlane( ptStart, plSide) > - TOL_OPEN_DRILL && vtN * plSide.GetVersN() > COS_ALMOST_PERP) {
nStartFace = i ;
dSinStart = sqrt( max( 0., 1 - vtN * plSide.GetVersN())) ;
break ;
}
}
double dStartAgg = (( nStartFace == 0 || dSinStart < EPS_SMALL) ? 0 : dRad * dSinStart + LEN_EXTRUS_AGG) ;
// verifico se fine su faccia (o fuori)
int nEndFace = 0 ;
double dSinEnd = 0 ;
for ( int i = BTL_SIDE_FRONT ; i <= BTL_SIDE_LEFT ; ++ i) {
Plane3d plSide = GetSidePlane( i) ;
if ( DistPointPlane( ptEnd, plSide) > - TOL_OPEN_DRILL && - vtN * plSide.GetVersN() > COS_ALMOST_PERP) {
nEndFace = i ;
dSinEnd = sqrt( max( 0., 1 + vtN * plSide.GetVersN())) ;
break ;
}
}
double dEndAgg = (( nEndFace == 0 || 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( vtN) ;
// creo la superficie trimesh laterale del foro
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, - vtN * ( dDepth + dStartAgg + dEndAgg)))
return false ;
pStm->Translate( vtN * dStartAgg) ;
// se chiuso, creo la superficie trimesh di fondo del foro
if ( nEndFace == 0) {
PtrOwner<ISurfTriMesh> pStmBot( CreateSurfTriMesh()) ;
if ( IsNull( pStmBot) || ! pStmBot->CreateByPointCurve( ptStart, PL))
return false ;
pStmBot->Translate( - vtN * 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, vsUAtt) ;
// identificativi di geometrie ausiliarie
SetAuxId( nId, {nTId}) ;
// flag per apertura foro su inizio/fine
SetDrillEnds( nId, nStartFace, nEndFace) ;
// 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, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 12)
return false ;
// sistemo i dati
Point3d ptP( vdPar[0], vdPar[1], 0) ;
int nFlag = lround( 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]) < 100 * EPS_SMALL ? 100 * EPS_SMALL : vdPar[10]) ;
double dTenM2 = ( abs( vdPar[11]) < 100 * EPS_SMALL ? 100 * 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 {
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 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) ;
// creo la superficie trimesh laterale del tenone
PtrOwner<ISurfTriMesh> pStmTen( CreateSurfTriMesh()) ;
if ( IsNull( pStmTen) || ! pStmTen->CreateByExtrusion( PL, frTen.VersZ() * dTenH))
return false ;
pStm->DoSewing( *pStmTen) ;
// 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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// 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 = lround( 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 {
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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 11)
return false ;
// sistemo i dati
Point3d ptP( vdPar[0], vdPar[1], 0) ;
int nFlag = lround( 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 {
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
pCrvTen->Translate( - frMort.VersZ() * dMortD) ;
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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 12)
return false ;
// sistemo i dati
Point3d ptP( vdPar[0], vdPar[1], 0) ;
int nFlag = lround( 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] / 2 ;
if ( dFillet < DTMILL_DEF_RAD && dTenW + 2 * max( dFillet, 0.) >= 2 * DTMILL_DEF_RAD) {
dTenW -= 2 * ( DTMILL_DEF_RAD - max( dFillet, 0.)) ;
dFillet = 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 = dTenHW ;
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, ISurfTriMesh::RLT_ISOPAR))
return false ;
// 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, ISurfTriMesh::RLT_ISOPAR))
return false ;
// Creo la superficie trimesh di testa del tenone
PL2.Close() ;
PtrOwner<ISurfTriMesh> pStmCap( CreateSurfTriMesh()) ;
if ( IsNull( pStmCap) || ! pStmCap->CreateByPointCurve( ptCen, PL2))
return false ;
// Unisco le superfici nell'ordine opportuno
pStm->DoSewing( *pStmCap) ;
pStm->DoSewing( *pStmTen) ;
pStm->DoSewing( *pStmTen2) ;
// 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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// 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 = lround( vdPar[3]) ;
int nPock = lround( 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] / 2 ;
if ( dFillet < DTMILL_DEF_RAD && dMortW + 2 * max( dFillet, 0.) >= 2 * DTMILL_DEF_RAD) {
dMortW -= 2 * ( DTMILL_DEF_RAD - max( dFillet, 0.)) ;
dFillet = 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 = dMortHW ;
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> pStmSide( CreateSurfTriMesh()) ;
if ( IsNull( pStmSide) || ! pStmSide->CreateByTwoCurves( PL2, PL1, ISurfTriMesh::RLT_ISOPAR))
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, ISurfTriMesh::RLT_ISOPAR))
return false ;
// aggiungo la superficie trimesh di fondo della mortasa
PL1.Close() ;
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->CreateByPointCurve( ptCen, PL1))
return false ;
// Unisco le varie superfici
pStm->DoSewing( *pStmSide) ;
pStm->DoSewing( *pStmMrt) ;
// 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, vsUAtt) ;
// 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, const STRVECTOR& vsUAtt)
{
// 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 = lround( vdPar[3]) ;
int nPock = lround( 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] / 2 ;
if ( dFillet < DTMILL_DEF_RAD && dMortW + 2 * dFillet >= 2 * DTMILL_DEF_RAD) {
dMortW -= 2 * ( DTMILL_DEF_RAD - dFillet) ;
dFillet = 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 = dMortHW ;
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, ISurfTriMesh::RLT_ISOPAR))
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, ISurfTriMesh::RLT_ISOPAR))
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, vsUAtt) ;
// identificativi di geometrie ausiliarie
SetAuxId( nId, {nTId}) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddMarking( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, int nSPar, const DBLVECTOR& vdPar, const string& sPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 8)
return false ;
// sistemo i dati
Point3d ptP( vdPar[0], vdPar[1], 0) ;
int nFlag = lround( vdPar[2]) ;
double dAng = Clamp( vdPar[3], 1., 180.) ;
double dIntAng = Clamp( vdPar[4], 0., 179.) ;
double dWidth = Clamp( vdPar[5], 0., 50000.) ;
double dQuadH = Clamp( vdPar[6], 0., 50000.) ;
if ( abs( dQuadH) < EPS_SMALL)
dQuadH = GetSideWidth( nSide) - ptP.y ;
double dTextH = Clamp( vdPar[7], 0., 50000.) ;
Vector3d vtD = FromPolar( 1, dAng) ;
if ( nGroup == 4)
vtD.Mirror( X_AX) ;
// riferimento della faccia
Frame3d frRef = GetSideFrame( nSide) ;
int nMainId = GDB_ID_NULL ;
INTVECTOR vAuxId ;
// gestione marcatura
if ( (nFlag & 1) == 0) {
// una sola linea orizzontale
if ( abs( dAng - 180.) < EPS_ANG_SMALL) {
// creo la linea
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
if ( IsNull( pLine))
return false ;
// assegno i dati
if ( ! pLine->SetPVL( ptP, vtD, dQuadH))
return false ;
// imposto estrusione
pLine->SetExtrusion( Z_AX) ;
// porto la linea nel piano della faccia
pLine->ToGlob( frRef) ;
// eseguo trim della curva con le facce della trave
if ( TrimFlatCurveWithBox( pLine)) {
// inserisco la linea nel DB geometrico
nMainId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pLine)) ;
if ( nMainId == GDB_ID_NULL)
return false ;
}
}
// una o due linee inclinate e parallele
else if ( abs( dWidth) < EPS_SMALL || abs( dIntAng) < EPS_ANG_SMALL) {
// dati
double dLen = dQuadH / vtD.y ;
Point3d ptQ = ptP + X_AX * (( nGroup == 3) ? - dWidth : dWidth) ;
// creo la prima linea
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
if ( IsNull( pLine))
return false ;
// assegno i dati
if ( ! pLine->SetPVL( ptP, vtD, dLen))
return false ;
// imposto estrusione
pLine->SetExtrusion( Z_AX) ;
// porto la linea nel piano della faccia
pLine->ToGlob( frRef) ;
// eseguo trim della curva con le facce della trave
if ( TrimFlatCurveWithBox( pLine)) {
// inserisco la linea nel DB geometrico
nMainId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pLine)) ;
if ( nMainId == GDB_ID_NULL)
return false ;
}
// se richiesto, creo la seconda linea
if ( abs( dWidth) > EPS_SMALL) {
PtrOwner<ICurveLine> pLine2( CreateCurveLine()) ;
if ( IsNull( pLine2))
return false ;
// assegno i dati
if ( ! pLine2->SetPVL( ptQ, vtD, dLen))
return false ;
// imposto estrusione
pLine2->SetExtrusion( Z_AX) ;
// porto la linea nel piano della faccia
pLine2->ToGlob( frRef) ;
// eseguo trim della curva con le facce della trave
if ( TrimFlatCurveWithBox( pLine2)) {
// inserisco la linea nel DB geometrico
int nId2 = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pLine2)) ;
if ( nId2 == GDB_ID_NULL)
return false ;
if ( nMainId == GDB_ID_NULL)
nMainId = nId2 ;
else
vAuxId.emplace_back( nId2) ;
}
}
}
// quadrangolo
else {
// dati
double dLen = dQuadH / vtD.y ;
Vector3d vtE = vtD ; vtE.Rotate( Z_AX, (( nGroup == 3) ? dIntAng : - dIntAng)) ;
double dLen2 = GetSideWidth( nSide) ;
if ( abs( vtE.x) > EPS_SMALL)
dLen2 = dWidth / abs( vtE.x) ;
// creo la prima linea
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
if ( IsNull( pLine))
return false ;
// assegno i dati
if ( ! pLine->SetPVL( ptP, vtD, dLen))
return false ;
// la inserisco nella composita
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
if ( IsNull( pCompo) || ! pCompo->AddCurve( Release( pLine)))
return false ;
// aggiungo le successive linee
pCompo->AddLine( ptP + vtD * dLen + vtE * dLen2) ;
pCompo->AddLine( ptP + vtE * dLen2) ;
pCompo->Close() ;
// imposto estrusione
pCompo->SetExtrusion( Z_AX) ;
// porto la curva nel piano della faccia
pCompo->ToGlob( frRef) ;
// eseguo trim della curva con le facce della trave
if ( TrimFlatCurveWithBox( pCompo)) {
// inserisco la linea nel DB geometrico
nMainId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCompo)) ;
if ( nMainId == GDB_ID_NULL)
return false ;
}
}
}
// gestione testo
// !!! DA FARE !!!
// assegno i dati principali
if ( nMainId != GDB_ID_NULL) {
// nome e info con tipo
SetNameAndInfo( nMainId, nGroup, nProc, nSide, sDes, nProcId) ;
// parametri
SetParams( nMainId, vnDPar, vdPar, vsUAtt) ;
string sKey = IKEY_PAR + ToString( nSPar, 2) ;
m_pGDB->SetInfo( nMainId, sKey, sPar) ;
// identificativi di geometrie ausiliarie
SetAuxId( nMainId, vAuxId) ;
// colore per linee di marcatura e testi
m_pGDB->SetMaterial( nMainId, m_MarkCol) ;
for (auto nId : vAuxId)
m_pGDB->SetMaterial( nId, m_MarkCol) ;
}
// altrimenti emetto segnalazione
else {
string sOut = " Warning : Empty Process (" + ToString( nGroup) + "-" + ToString( nProc, 3) + "-" + ToString( nSide) +
") on line " + ToString( m_nBtlLine) ;
LOG_WARN( GetEExLogger(), sOut.c_str())
}
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, const STRVECTOR& vsUAtt)
{
// 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, vsUAtt) ;
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::AddSimpleScarf( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 6)
return false ;
// sistemo i dati
double dStartX = vdPar[0] ; // P01
double dDepthRef = Clamp( vdPar[1], 0., 50000.) ; // P11
double dDepthOpp = Clamp( vdPar[2], 0., 50000.) ; // P12
double dLength = Clamp( vdPar[3], 0., 50000.) ; // P13
double dHoDiam1 = Clamp( vdPar[4], 0., 1000.) ; // P14
double dHoDiam2 = Clamp( vdPar[5], 0., 1000.) ; // P15
// calcolo la normale principale
Vector3d vtN = ( nGroup == 2 ? - X_AX : X_AX) ;
// punti di riferimento
Point3d ptP1( dStartX, 0, - dDepthRef) ;
Point3d ptP2( dStartX - vtN.x * dLength, 0, - GetSideHeight( nSide) + dDepthOpp) ;
// creo il primo poligono di taglio
Polygon3d plyFace1 ;
if ( ! CreatePolygonInBox( ptP1, vtN, nSide, plyFace1))
return false ;
// creo il secondo poligono di taglio
Vector3d vtM = ptP2 - ptP1 ;
vtM.Normalize() ;
vtM.Rotate( Y_AX, ( nGroup == 2 ? ANG_RIGHT : - ANG_RIGHT)) ;
Polygon3d plyFace2 ;
if ( ! CreatePolygonInBox( ptP1, vtM, nSide, plyFace2))
return false ;
// creo il terzo poligono di taglio
Polygon3d plyFace3 ;
if ( ! CreatePolygonInBox( ptP2, vtN, nSide, plyFace3))
return false ;
// trim tra queste facce
if ( ! TrimPolygons( plyFace1, plyFace2, true, false) ||
! TrimPolygons( plyFace2, plyFace3, false, false))
return false ;
// creo la trimesh dalle facce
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm))
return false ;
if ( ! DoSewing( pStm, plyFace1) ||
! DoSewing( pStm, plyFace2) ||
! DoSewing( pStm, plyFace3))
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, vsUAtt) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddScarfJoint( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 9)
return false ;
// sistemo i dati
double dStartX = vdPar[0] ; // P01
double dInclination = Clamp( vdPar[1], 0., 90.) ; // P07
int nType = lround( vdPar[2]) ; // P09
double dLapLength = Clamp( vdPar[3], 0., 50000.) ; // P10
double dLapDepth = Clamp( vdPar[4], 0., 50000.) ; // P11
double dDepthOpp = Clamp( vdPar[5], 0., 50000.) ; // P12
double dLength = Clamp( vdPar[6], 0., 50000.) ; // P13
double dHoDiam1 = Clamp( vdPar[7], 0., 1000.) ; // P14
double dHoDiam2 = Clamp( vdPar[8], 0., 1000.) ; // P15
double dHeight = GetSideHeight( nSide) ;
// aggiustamenti
if ( nType == 0) {
// devo calcolare dInclination, dLapLength e dDepthOpp (vedi note in Wiki)
DBLVECTOR vdPoly( 3) ;
vdPoly[0] = - dLapDepth * dLapDepth * ( dLength * dLength + dHeight * dHeight) ;
vdPoly[1] = 2 * dHeight * dLapDepth * dLapDepth ;
vdPoly[2] = dLength * dLength - dLapDepth * dLapDepth ;
DBLVECTOR vdRoot ;
int nRoots = PolynomialRoots( 2, vdPoly, vdRoot) ;
if ( nRoots > 0 && vdRoot[0] > EPS_SMALL && vdRoot[0] < dHeight)
dDepthOpp = vdRoot[0] ;
else if ( nRoots > 1 && vdRoot[1] > EPS_SMALL && vdRoot[1] < dHeight)
dDepthOpp = vdRoot[1] ;
else
return false ;
dInclination = acos( dLapDepth / dDepthOpp) * RADTODEG ;
dLapLength = ( sqrt( dLength * dLength + ( dHeight - dDepthOpp) * ( dHeight - dDepthOpp)) - dDepthOpp * sin( dInclination * DEGTORAD)) / 2 ;
}
// calcolo la direzione principale e quella ortogonale
Vector3d vtV1 = - X_AX ;
vtV1.Rotate( Y_AX, dInclination) ;
Vector3d vtV2 = vtV1 ;
vtV2.Rotate( Y_AX, ANG_RIGHT) ;
// punti di riferimento
Point3d ptP( dStartX + dLength, 0, -dHeight) ;
Point3d ptQ = ptP + Z_AX * dDepthOpp ;
Point3d ptR = ptQ + vtV1 * dLapLength ;
Point3d ptS = ptR - vtV2 * dLapDepth ;
Point3d ptT = ptP + vtV1 * dLength / abs( vtV1.x) ;
Point3d ptU( dStartX, 0, 0) ;
if ( nType == -1) {
ptP = ptQ - vtV2 * dDepthOpp / vtV2.z ;
ptU = ptT + vtV2 * ( - ptT.z) / vtV2.z ;
}
// creo il profilo
PolyLine PL ;
PL.AddUPoint( 0, ptP) ;
PL.AddUPoint( 1, ptQ) ;
PL.AddUPoint( 2, ptR) ;
PL.AddUPoint( 3, ptS) ;
PL.AddUPoint( 4, ptT) ;
PL.AddUPoint( 5, ptU) ;
if ( nGroup == 1)
PL.Mirror( ptT, X_AX) ;
// lo porto in globale
Frame3d frSide = GetSideFrame( nSide) ;
PL.ToGlob( frSide) ;
// definisco la superficie
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, frSide.VersY() * GetSideWidth( nSide)))
return false ;
if ( nGroup == 1)
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 ;
// nome e info con tipo
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
// parametri
SetParams( nId, vnDPar, vdPar, vsUAtt) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddStepJoint( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 7)
return false ;
// sistemo i dati
double dStartX = vdPar[0] ; // P01
int nType = lround( vdPar[1]) ; // P04
double dInclination = Clamp( vdPar[2], 0.1, 179.9) ; // P07
double dStepDepth = Clamp( vdPar[3], 0., 1000.) ; // P11
double dHeelDepth = Clamp( vdPar[4], 0., 1000.) ; // P12
double dTenHeight = Clamp( vdPar[5], 0., 1000.) ; // P14
double dTenWidth = Clamp( vdPar[6], 0., 1000.) ; // P15
// gestione angolo ottuso
bool bMirrZ = ( dInclination > ANG_RIGHT) ;
if ( bMirrZ) {
dInclination = ANG_STRAIGHT - dInclination ;
dStartX += ( nGroup == 2 ? -1 : 1) * GetSideHeight( nSide) / tan( dInclination * DEGTORAD) ;
}
// controllo del tipo
if ( dStepDepth > EPS_SMALL && dHeelDepth > EPS_SMALL)
nType = 0 ;
else if ( dHeelDepth <= EPS_SMALL || abs( dInclination - ANG_RIGHT) < EPS_ANG_SMALL ||
dHeelDepth / cos( dInclination * DEGTORAD) > GetSideHeight( nSide) - EPS_SMALL)
nType = 1 ;
// definizione punti notevoli
Point3d ptP( dStartX, 0, 0) ;
Vector3d vtV1 = - X_AX ;
vtV1.Rotate( Y_AX, dInclination) ;
Point3d ptQ = ptP - vtV1 * GetSideHeight( nSide) / vtV1.z ;
if ( dHeelDepth > EPS_SMALL)
ptQ += - X_AX * dHeelDepth / sin( dInclination * DEGTORAD) ;
Point3d ptS = ptQ ;
if ( nType == 0)
ptS += Z_AX * dHeelDepth / cos( dInclination * DEGTORAD) ;
Point3d ptT = ptP ;
if ( dStepDepth > EPS_SMALL) {
double dAngT = ( ANG_STRAIGHT - dInclination) / 2 ;
Vector3d vtV2 = vtV1 ;
vtV2.Rotate( Y_AX, dAngT) ;
ptT += - vtV2 * dStepDepth / sin( dAngT * DEGTORAD) ;
}
// creazione profilo
PolyLine PL ;
PL.AddUPoint( 0, ptP) ;
PL.AddUPoint( 1, ptT) ;
PL.AddUPoint( 2, ptS) ;
PL.AddUPoint( 3, ptQ) ;
if ( bMirrZ) {
PL.Mirror( Point3d( 0, 0, - GetSideHeight( nSide) / 2), Z_AX) ;
PL.Invert() ;
}
if ( nGroup == 1)
PL.Mirror( ptP, X_AX) ;
// lo porto in globale
Frame3d frSide = GetSideFrame( nSide) ;
PL.ToGlob( frSide) ;
// definisco la superficie
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, frSide.VersY() * GetSideWidth( nSide)))
return false ;
if ( nGroup == 2)
pStm->Invert() ;
// 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 ;
// nome e info con tipo
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
// parametri
SetParams( nId, vnDPar, vdPar, vsUAtt) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddStepJointNotch( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 7)
return false ;
// sistemo i dati
double dStartX = vdPar[0] ; // P01
double dStartY = vdPar[1] ; // P02
int nType = lround( vdPar[2]) ; // P04
double dInclination = Clamp( vdPar[3], 0.1, 179.9) ; // P07
double dWidth = Clamp( vdPar[4], 0., 50000.) ; // P10
double dStepDepth = Clamp( vdPar[5], 0., 1000.) ; // P11
double dHeelDepth = Clamp( vdPar[6], 0., 1000.) ; // P12
double dStructHeight = Clamp( vdPar[7], 0., 50000.) ; // P13
double dTenHeight = Clamp( vdPar[8], 0., 1000.) ; // P14
double dTenWidth = Clamp( vdPar[9], 0., 1000.) ; // P15
// gestione angolo ottuso
double dLen = dStructHeight / sin( dInclination * DEGTORAD) ;
bool bMirrX = ( dInclination > ANG_RIGHT) ;
if ( bMirrX) {
dInclination = ANG_STRAIGHT - dInclination ;
dStartX += ( nGroup == 4 ? dLen : - dLen) ;
}
// controllo del tipo
if ( dStepDepth > EPS_SMALL && dHeelDepth > EPS_SMALL)
nType = 0 ;
else if ( dHeelDepth <= EPS_SMALL || abs( dInclination - ANG_RIGHT) < EPS_ANG_SMALL ||
dHeelDepth / cos( dInclination * DEGTORAD) > dLen - EPS_SMALL)
nType = 1 ;
// riferimento della faccia
Frame3d frSide = GetSideFrame( nSide) ;
// definizione punti notevoli
Vector3d vtV1 = X_AX ;
vtV1.Rotate( Y_AX, - dInclination) ;
Point3d ptP( dStartX, dStartY, 0) ;
Point3d ptQ = ptP + X_AX * dLen ;
Point3d ptR = ptQ ;
if ( dHeelDepth > EPS_SMALL)
ptR += - vtV1 * dHeelDepth / sin( dInclination * DEGTORAD) ;
Point3d ptS ;
if ( nType == 0)
ptS = ptQ - X_AX * dHeelDepth / ( sin( dInclination * DEGTORAD) * cos( dInclination * DEGTORAD)) ;
else
ptS = ptR ;
Point3d ptT = ptP ;
if ( dStepDepth > EPS_SMALL) {
double dAngT = ( ANG_STRAIGHT - dInclination) / 2 ;
Vector3d vtV2 = vtV1 ;
vtV2.Rotate( Y_AX, - dAngT) ;
ptT += - vtV2 * dStepDepth / sin( dAngT * DEGTORAD) ;
}
// creazione profilo
double dU = 0 ;
PolyLine PL ;
if ( ! AreSamePointApprox( ptP, ptT)) {
PL.AddUPoint( dU, ptP) ;
PL.AddUPoint( ++dU, ptT) ;
// se doppio lobo laterale, abbasso il centro per non avere problemi
if ( ! AreSamePointApprox( ptS, ptR))
ptS -= Z_AX * 10 * EPS_SMALL ;
}
else if ( AreSamePointApprox( ptS, ptR))
PL.AddUPoint( dU, ptP) ;
PL.AddUPoint( ++dU, ptS) ;
PL.AddUPoint( ++dU, ptR) ;
PL.AddUPoint( ++dU, ptQ) ;
if ( bMirrX) {
PL.Mirror( ptP, X_AX) ;
PL.Invert() ;
}
if ( nGroup == 3)
PL.Mirror( ptP, X_AX) ;
// lo porto in globale
PL.ToGlob( frSide) ;
// definisco la superficie
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, frSide.VersY() * dWidth))
return false ;
if ( nGroup == 3)
pStm->Invert() ;
// definisco ed aggiungo eventuale faccia anteriore
if ( dStartY > EPS_SMALL) {
// profilo superiore
PolyLine PL2 = PL ;
PL2.Scale( frSide, 1, 1, 0) ;
// creo la superficie rigata
PtrOwner<ISurfTriMesh> pSfr( CreateSurfTriMesh()) ;
if ( IsNull( pSfr) || ! pSfr->CreateByTwoCurves( PL, PL2, ISurfTriMesh::RLT_ISOPAR))
return false ;
// la unisco alla superficie principale
if ( ! pStm->DoSewing( *pSfr))
return false ;
}
// definisco ed aggiungo eventuale faccia posteriore
if ( dStartY + dWidth < GetSideWidth( nSide) - EPS_SMALL) {
// profilo superiore
PolyLine PL2 = PL ;
PL2.Scale( frSide, 1, 1, 0) ;
// creo la superficie rigata
PtrOwner<ISurfTriMesh> pSfr( CreateSurfTriMesh()) ;
if ( IsNull( pSfr) || ! pSfr->CreateByTwoCurves( PL, PL2, ISurfTriMesh::RLT_ISOPAR))
return false ;
// la inverto e la traslo
pSfr->Invert() ;
pSfr->Translate( frSide.VersY() * dWidth) ;
// la unisco alla superficie principale
if ( ! pStm->DoSewing( *pSfr))
return false ;
}
// 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 ;
// nome e info con tipo
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
// parametri
SetParams( nId, vnDPar, vdPar, vsUAtt) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddProfileFront( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 7)
return false ;
// sistemo i dati
double dP01 = vdPar[0] ; // P01
double dP03 = Clamp( vdPar[1], -1000., 1000.) ; // P03
double dP06 = Clamp( vdPar[2], 0., 180.) ; // P06
double dP07 = Clamp( vdPar[3], 0., 180.) ; // P07
double dP08 = Clamp( vdPar[4], -180., 180.) ; // P08
double dP11 = Clamp( vdPar[5], -1000., 1000.) ; // P11
double dP12 = Clamp( vdPar[6], -1000., 1000.) ; // P12
// faccia di riferimento
int nRefSide = ( ( nSide - 1) >= BTL_SIDE_FRONT ? ( nSide - 1) : BTL_SIDE_TOP) ;
// calcolo i punti
double dPos = (( nGroup == 3) ? GetSideLength( nRefSide) - dP01 : dP01) ;
Point3d ptC1( dPos + abs( dP11), dP03 + abs( dP11), 0) ;
Vector3d vtDirI1 = - X_AX ;
vtDirI1.Rotate( Z_AX, dP08) ;
Point3d ptP2 = ptC1 + vtDirI1 * abs( dP11) ;
Point3d ptP1 ;
if ( ! TrimRayWithFaceContour( ptP2, vtDirI1, nRefSide, ptP1))
ptP1 = ptP2 ;
Vector3d vtDirF1 = vtDirI1 ;
vtDirF1.Rotate( Z_AX, dP06) ;
Point3d ptP3 = ptC1 + vtDirF1 * abs( dP11) ;
Vector3d vtDirI2 = - vtDirF1 ;
Point3d ptC2 = ptP3 - vtDirI2 * abs( dP12) ;
Vector3d vtDirF2 = vtDirI2 ;
vtDirF2.Rotate( Z_AX, -dP07) ;
Point3d ptP4 = ptC2 + vtDirF2 * abs( dP12) ;
Point3d ptP5 ;
if ( abs( dP12) < EPS_SMALL || dP07 < EPS_ANG_SMALL) {
if ( ! TrimRayWithFaceContour( ptP4, vtDirF1, nRefSide, ptP5))
ptP5 = ptP4 ;
}
else {
Vector3d vtTgF2 = vtDirF2 ;
vtTgF2.Rotate( Z_AX, -90) ;
if ( ! TrimRayWithFaceContour( ptP4, vtTgF2, nRefSide, ptP5))
ptP5 = ptP4 ;
}
double dBulge1 = ( abs( dP11) > EPS_SMALL ? tan( 0.25 * dP06 * DEGTORAD) : 0) ;
double dBulge2 = ( abs( dP12) > EPS_SMALL ? tan( 0.25 * -dP07 * DEGTORAD) : 0) ;
// costruisco la curva del profilo
PolyArc PA ;
PA.AddUPoint( 0, ptP1, 0) ;
PA.AddUPoint( 1, ptP2, 0) ;
PA.ModifyLastBulge( (( dP11 < 0) ? -dBulge1 : dBulge1)) ;
PA.AddUPoint( 2, ptP3, 0) ;
PA.ModifyLastBulge( (( dP12 < 0) ? -dBulge2 : dBulge2)) ;
PA.AddUPoint( 3, ptP4, 0) ;
PA.AddUPoint( 4, ptP5, 0) ;
PtrOwner<ICurveComposite> pCrvCo( CreateCurveComposite()) ;
if ( IsNull( pCrvCo) || ! pCrvCo->FromPolyArc( PA))
return false ;
pCrvCo->SetExtrusion( Z_AX) ;
pCrvCo->SetThickness( - GetSideWidth( nSide)) ;
// se gruppo 3, simmetrico rispetto a X
if ( nGroup == 3)
pCrvCo->Mirror( Point3d( 0.5 * GetSideLength( nRefSide), 0, 0), X_AX) ;
// sistemo per riferimento faccia
Frame3d frRef ;
frRef = GetSideFrame( nRefSide) ;
pCrvCo->ToGlob( frRef) ;
// eseguo trim della curva con le facce della trave
TrimFlatCurveWithBox( pCrvCo) ;
// creo la superficie di estrusione
PolyLine PL ;
pCrvCo->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL) ;
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, - frRef.VersZ() * GetSideWidth( nSide)))
return false ;
if ( nGroup == 4)
pStm->Invert() ;
// 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 ;
// esterno deve sempre essere a destra della curva
if ( nGroup == 3) {
pCrvCo->Translate( - frRef.VersZ() * GetSideWidth( nSide)) ;
pCrvCo->SetExtrusion( - frRef.VersZ()) ;
}
// inserisco la curva nel DB geometrico
int nTId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvCo)) ;
if ( nTId == GDB_ID_NULL)
return false ;
// nome e info con tipo
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
// parametri
SetParams( nId, vnDPar, vdPar, vsUAtt) ;
// identificativi di geometrie ausiliarie
SetAuxId( nId, {nTId}) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddProfileHeadCoCo( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 6)
return false ;
// sistemo i dati
double dP01 = vdPar[0] ;
double dP11 = Clamp( vdPar[1], 0., 1000.) ;
double dP12 = Clamp( vdPar[2], -1000., 1000.) ;
double dP13 = Clamp( vdPar[3], 0., 1000.) ;
double dP14 = Clamp( vdPar[4], -1000., 1000.) ;
double dP15 = Clamp( vdPar[5], 0., 1000.) ;
Point3d ptP1( dP01, dP14 + dP11 + dP12, 0) ;
Point3d ptP2( dP01 + dP13, dP14 + dP11 + dP12, 0) ;
Point3d ptP3( dP01 + dP13, dP14 + dP11, 0) ;
Point3d ptP4( dP01 + dP13 + dP11, dP14, 0) ;
Point3d ptP5( dP01 + dP13 + dP11 + dP15, dP14, 0) ;
Point3d ptP6( dP01 + dP13 + dP11 + dP15, 0, 0) ;
// costruisco la curva del profilo
PolyArc PA ;
PA.AddUPoint( 0, ptP1, 0) ;
PA.AddUPoint( 0, ptP2, 0) ;
PA.AddUPoint( 0, ptP3, 0) ;
PA.ModifyLastBulge( (( nProc == 101) ? -BULGE_90D : BULGE_90D)) ;
PA.AddUPoint( 0, ptP4, 0) ;
PA.AddUPoint( 0, ptP5, 0) ;
PA.AddUPoint( 0, ptP6, 0) ;
PtrOwner<ICurveComposite> pCrvCo( CreateCurveComposite()) ;
if ( IsNull( pCrvCo) || ! pCrvCo->FromPolyArc( PA))
return false ;
pCrvCo->SetExtrusion( Z_AX) ;
pCrvCo->SetThickness( - GetSideWidth( nSide)) ;
// se gruppo 3, simmetrico rispetto a X
if ( nGroup == 3)
pCrvCo->Mirror( ptP1, X_AX) ;
// sistemo per riferimento faccia
Frame3d frRef ;
int nRefSide = ( ( nSide - 1) >= BTL_SIDE_FRONT ? ( nSide - 1) : BTL_SIDE_TOP) ;
frRef = GetSideFrame( nRefSide) ;
pCrvCo->ToGlob( frRef) ;
// eseguo trim della curva con le facce della trave
TrimFlatCurveWithBox( pCrvCo) ;
// creo la superficie di estrusione
PolyLine PL ;
pCrvCo->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL) ;
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, - frRef.VersZ() * GetSideWidth( nSide)))
return false ;
if ( nGroup == 4)
pStm->Invert() ;
// 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 ;
// esterno deve sempre essere a destra della curva
if ( nGroup == 3) {
pCrvCo->Translate( - frRef.VersZ() * GetSideWidth( nSide)) ;
pCrvCo->SetExtrusion( - frRef.VersZ()) ;
}
// inserisco la curva nel DB geometrico
int nTId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvCo)) ;
if ( nTId == GDB_ID_NULL)
return false ;
// nome e info con tipo
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
// parametri
SetParams( nId, vnDPar, vdPar, vsUAtt) ;
// identificativi di geometrie ausiliarie
SetAuxId( nId, {nTId}) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddProfileHeadCambered( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 7)
return false ;
// sistemo i dati
Point3d ptS( vdPar[0], vdPar[2], 0) ;
Point3d ptE( vdPar[0] + vdPar[1], vdPar[5], 0) ;
double dMax = vdPar[3] ;
double dMin = vdPar[4] ;
int nFlag = lround( vdPar[6]) ;
// calcolo i punti di controllo
const double COEFF_PCMAX = 1. / 3. ;
const double COEFF_PCMIN = 2. / 3. ;
const double PCTRL_COEFF = 1.5 ;
double dRef1 = vdPar[2] * ( 1 - COEFF_PCMAX) + vdPar[5] * COEFF_PCMAX ;
double dRef2 = vdPar[2] * ( 1 - COEFF_PCMIN) + vdPar[5] * COEFF_PCMIN ;
Point3d ptCmax( vdPar[0] + vdPar[1] * COEFF_PCMAX, dRef1 + PCTRL_COEFF * ( dMax - dRef1), 0) ;
Point3d ptCmin( vdPar[0] + vdPar[1] * COEFF_PCMIN, dRef2 + PCTRL_COEFF * ( dMin - dRef2), 0) ;
// costruisco la curva del profilo
PtrOwner<ICurveBezier> pCrv( CreateCurveBezier()) ;
if ( IsNull( pCrv))
return false ;
pCrv->Init( 3, false) ;
pCrv->SetControlPoint( 0, ptS) ;
pCrv->SetControlPoint( 1, ptCmax) ;
pCrv->SetControlPoint( 2, ptCmin) ;
pCrv->SetControlPoint( 3, ptE) ;
// verifico minimo/massimo
const double MAX_ERR = 0.5 ;
for ( int i = 1 ; i <= 10 ; ++ i) {
BBox3d b3Crv ;
pCrv->GetLocalBBox( b3Crv, BBF_EXACT) ;
double dDeltaMax = dMax - b3Crv.GetMax().y ;
double dDeltaMin = dMin - b3Crv.GetMin().y ;
if ( abs( dDeltaMax) > MAX_ERR || abs( dDeltaMin) > MAX_ERR) {
ptCmax += Vector3d( 0, PCTRL_COEFF * dDeltaMax, 0) ;
pCrv->SetControlPoint( 1, ptCmax) ;
ptCmin += Vector3d( 0, PCTRL_COEFF * dDeltaMin, 0) ;
pCrv->SetControlPoint( 2, ptCmin) ;
}
else
break ;
}
// la approssimo con archi e rette
PtrOwner<ICurveComposite> pCrvCo( CreateCurveComposite()) ;
if ( IsNull( pCrvCo) || ! pCrvCo->AddCurve( Release( pCrv)))
return false ;
pCrvCo->SetExtrusion( Z_AX) ;
pCrvCo->SetThickness( - GetSideWidth( nSide)) ;
pCrvCo->ArcsBezierCurvesToArcsPerpExtr( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG) ;
// aggiungo la linea finale
Point3d ptEnd ; pCrvCo->GetEndPoint( ptEnd) ;
Vector3d vtEnd ; pCrvCo->GetEndDir( vtEnd) ; vtEnd.Rotate( Z_AX, -90) ;
double dLen = ptEnd.y / abs( vtEnd.y) ;
pCrvCo->AddLine( ptEnd + vtEnd * dLen) ;
// se gruppo 3, simmetrico rispetto a X
if ( nGroup == 3)
pCrvCo->Mirror( ptS, X_AX) ;
// sistemo per riferimento faccia
Frame3d frRef ;
int nRefSide = ( ( nSide - 1) >= BTL_SIDE_FRONT ? ( nSide - 1) : BTL_SIDE_TOP) ;
frRef = GetSideFrame( nRefSide) ;
pCrvCo->ToGlob( frRef) ;
// eseguo trim della curva con le facce della trave
TrimFlatCurveWithBox( pCrvCo) ;
// creo la superficie di estrusione
PolyLine PL ;
pCrvCo->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL) ;
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, - frRef.VersZ() * GetSideWidth( nSide)))
return false ;
if ( nGroup == 4)
pStm->Invert() ;
// 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 ;
// esterno deve sempre essere a destra della curva
if ( nGroup == 3) {
pCrvCo->Translate( - frRef.VersZ() * GetSideWidth( nSide)) ;
pCrvCo->SetExtrusion( - frRef.VersZ()) ;
}
// inserisco la curva nel DB geometrico
int nTId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvCo)) ;
if ( nTId == GDB_ID_NULL)
return false ;
// nome e info con tipo
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
// parametri
SetParams( nId, vnDPar, vdPar, vsUAtt) ;
// identificativi di geometrie ausiliarie
SetAuxId( nId, {nTId}) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddProfileHead( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 16)
return false ;
// assegno i dati
double dP01 = vdPar[0] ; // P01
int nFlag = lround( vdPar[1]) ; // P04
double dP09 = Clamp( vdPar[2], 0., 1000.) ; // P09
double dP10 = Clamp( vdPar[3], 0., 1000.) ; // P10
double dP11 = Clamp( vdPar[4], 0., 1000.) ; // P11
double dP12 = Clamp( vdPar[5], 0., 1000.) ; // P12
double dP13 = Clamp( vdPar[6], 0., 1000.) ; // P13
double dP14 = Clamp( vdPar[7], 0., 1000.) ; // P14
double dP15 = Clamp( vdPar[8], 0., 1000.) ; // P15
double dP16 = Clamp( vdPar[9], 0., 1000.) ; // P16
double dP17 = Clamp( vdPar[10], 0., 1000.) ; // P17
double dP18 = Clamp( vdPar[11], 0., 1000.) ; // P18
double dP19 = Clamp( vdPar[12], 0., 1000.) ; // P19
double dP20 = Clamp( vdPar[13], 0., 1000.) ; // P20
double dP21 = Clamp( vdPar[14], 0., 1000.) ; // P21
double dP22 = Clamp( vdPar[15], 0., 1000.) ; // P22
// sistemo i dati
double dBulgeArc1 = 0 ;
if ( abs( dP12) > EPS_SMALL && abs( dP13) < EPS_SMALL && abs( dP14) < EPS_SMALL) {
dP13 = dP12 ;
dBulgeArc1 = BULGE_90D ;
}
else if ( abs( dP12) > EPS_SMALL && abs( dP13) > EPS_SMALL)
dBulgeArc1 = 2 * dP14 / sqrt( dP12 * dP12 + dP13 * dP13) ;
double dBulgeArc2 = 0 ;
if ( abs( dP18) > EPS_SMALL && abs( dP19) < EPS_SMALL && abs( dP20) < EPS_SMALL) {
dP19 = dP18 ;
dBulgeArc2 = BULGE_90D ;
}
else if ( abs( dP18) > EPS_SMALL && abs( dP19) > EPS_SMALL)
dBulgeArc2 = 2 * dP20 / sqrt( dP18 * dP18 + dP19 * dP19) ;
// calcolo i punti
Point3d ptP1( dP01, dP22 + dP19 + dP16 + dP13 + dP10, 0) ;
Point3d ptP2( dP01 + dP09, dP22 + dP19 + dP16 + dP13 + dP10, 0) ;
Point3d ptP3( dP01 + dP09, dP22 + dP19 + dP16 + dP13, 0) ;
Point3d ptP4( dP01 + dP09 + dP11, dP22 + dP19 + dP16 + dP13, 0) ;
Point3d ptP5( dP01 + dP09 + dP11 + dP12, dP22 + dP19 + dP16, 0) ;
Point3d ptP6( dP01 + dP09 + dP11 + dP12 + dP15, dP22 + dP19 + dP16, 0) ;
Point3d ptP7( dP01 + dP09 + dP11 + dP12 + dP15, dP22 + dP19, 0) ;
Point3d ptP8( dP01 + dP09 + dP11 + dP12 + dP15 + dP17, dP22 + dP19, 0) ;
Point3d ptP9( dP01 + dP09 + dP11 + dP12 + dP15 + dP17 + dP18, dP22, 0) ;
Point3d ptPA( dP01 + dP09 + dP11 + dP12 + dP15 + dP17 + dP18 + dP21, dP22, 0) ;
Point3d ptPB( dP01 + dP09 + dP11 + dP12 + dP15 + dP17 + dP18 + dP21, 0, 0) ;
// costruisco la curva del profilo
PolyArc PA ;
PA.AddUPoint( 0, ptP1, 0) ;
PA.AddUPoint( 0, ptP2, 0) ;
PA.AddUPoint( 0, ptP3, 0) ;
PA.AddUPoint( 0, ptP4, 0) ;
PA.ModifyLastBulge( (( nFlag == 0 || nFlag == 2) ? -dBulgeArc1 : dBulgeArc1)) ;
PA.AddUPoint( 0, ptP5, 0) ;
PA.AddUPoint( 0, ptP6, 0) ;
PA.AddUPoint( 0, ptP7, 0) ;
PA.AddUPoint( 0, ptP8, 0) ;
PA.ModifyLastBulge( (( nFlag == 0 || nFlag == 1) ? -dBulgeArc2 : dBulgeArc2)) ;
PA.AddUPoint( 0, ptP9, 0) ;
PA.AddUPoint( 0, ptPA, 0) ;
PA.AddUPoint( 0, ptPB, 0) ;
PtrOwner<ICurveComposite> pCrvCo( CreateCurveComposite()) ;
if ( IsNull( pCrvCo) || ! pCrvCo->FromPolyArc( PA))
return false ;
pCrvCo->SetExtrusion( Z_AX) ;
pCrvCo->SetThickness( - GetSideWidth( nSide)) ;
// se gruppo 3, simmetrico rispetto a X
if ( nGroup == 3)
pCrvCo->Mirror( ptP1, X_AX) ;
// sistemo per riferimento faccia
Frame3d frRef ;
int nRefSide = ( ( nSide - 1) >= BTL_SIDE_FRONT ? ( nSide - 1) : BTL_SIDE_TOP) ;
frRef = GetSideFrame( nRefSide) ;
pCrvCo->ToGlob( frRef) ;
// eseguo trim della curva con le facce della trave
TrimFlatCurveWithBox( pCrvCo) ;
// creo la superficie di estrusione
PolyLine PL ;
pCrvCo->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL) ;
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, - frRef.VersZ() * GetSideWidth( nSide)))
return false ;
if ( nGroup == 4)
pStm->Invert() ;
// 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 ;
// esterno deve sempre essere a destra della curva
if ( nGroup == 3) {
pCrvCo->Translate( - frRef.VersZ() * GetSideWidth( nSide)) ;
pCrvCo->SetExtrusion( - frRef.VersZ()) ;
}
// inserisco la curva nel DB geometrico
int nTId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvCo)) ;
if ( nTId == GDB_ID_NULL)
return false ;
// nome e info con tipo
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
// parametri
SetParams( nId, vnDPar, vdPar, vsUAtt) ;
// identificativi di geometrie ausiliarie
SetAuxId( nId, {nTId}) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::AddRoundArch( int nGroup, int nProc, int nSide, const string& sDes, int nProcId,
const INTVECTOR& vnDPar, const DBLVECTOR& vdPar, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 3)
return false ;
// sistemo i dati
double dStartX = vdPar[0] ; // P01
double dCamber = Clamp( vdPar[1], -1000., 1000.) ; // P11
double dLength = Clamp( vdPar[2], 0., 30000.) ; // P12
// costruisco la curva del profilo
bool bConvex = ( dCamber < 0) ;
Point3d ptP1( dStartX - dLength / 2, ( bConvex ? - dCamber : 0), 0) ;
Point3d ptP2( dStartX, ( bConvex ? 10 * EPS_SMALL : dCamber), 0) ;
Point3d ptP3 = ptP1 + Vector3d( dLength, 0, 0) ;
PtrOwner<ICurve> pCrv ;
if ( ! pCrv.Set( GetArc3P( ptP1, ptP2, ptP3, false)))
return nullptr ;
PtrOwner<ICurveComposite> pCrvCo( CreateCurveComposite()) ;
if ( IsNull( pCrvCo) || ! pCrvCo->AddCurve( Release( pCrv)))
return false ;
pCrvCo->SetExtrusion( Z_AX) ;
pCrvCo->SetThickness( - GetSideWidth( nSide)) ;
// se convesso, aggiungo linea iniziale e finale
if ( bConvex) {
Point3d ptStart ; pCrvCo->GetStartPoint( ptStart) ;
Vector3d vtStart ; pCrvCo->GetStartDir( vtStart) ; vtStart.Rotate( Z_AX, -90) ;
double dLs = ptStart.y / abs( vtStart.y) ;
pCrvCo->AddLine( ptStart + vtStart * dLs, false) ;
Point3d ptEnd ; pCrvCo->GetEndPoint( ptEnd) ;
Vector3d vtEnd ; pCrvCo->GetEndDir( vtEnd) ; vtEnd.Rotate( Z_AX, -90) ;
double dLe = ptEnd.y / abs( vtEnd.y) ;
pCrvCo->AddLine( ptEnd + vtEnd * dLe) ;
}
// sistemo per riferimento faccia
Frame3d frRef ;
int nRefSide = ( ( nSide - 1) >= BTL_SIDE_FRONT ? ( nSide - 1) : BTL_SIDE_TOP) ;
frRef = GetSideFrame( nRefSide) ;
pCrvCo->ToGlob( frRef) ;
// creo la superficie di estrusione
PolyLine PL ;
pCrvCo->ApproxWithLines( CRV_LIN_APPROX, CRV_ANG_APPROX_DEG, ICurve::APL_STD, PL) ;
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->CreateByExtrusion( PL, - frRef.VersZ() * GetSideWidth( nSide)))
return false ;
pStm->Invert() ;
// 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 ;
// inserisco la curva nel DB geometrico
int nTId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nProcsId, Release( pCrvCo)) ;
if ( nTId == GDB_ID_NULL)
return false ;
// nome e info con tipo
SetNameAndInfo( nId, nGroup, nProc, nSide, sDes, nProcId) ;
// parametri
SetParams( nId, vnDPar, vdPar, vsUAtt) ;
// identificativi di geometrie ausiliarie
SetAuxId( nId, {nTId}) ;
// aggiusto l'outline
if ( UseProcessToTrimOutline( nId))
TrimOutline( nId) ;
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, const STRVECTOR& vsUAtt)
{
// verifica dei parametri
if ( vdPar.size() < 11)
return false ;
// sistemo i dati
int nType = lround( vdPar[6]) ; // P08
Point3d ptP( vdPar[0], vdPar[1], vdPar[2]) ; // P01, P02, P03
Point3d ptM ;
if ( nType == FreeContourEnt::ARC)
ptM.Set( vdPar[8], vdPar[9], vdPar[10]) ; // P10, P11, P12
double dDepth = vdPar[3] ; // P05
double dAng = vdPar[4] ; // P06
int nNextId = lround( vdPar[7]) ; // P09
int nPocket = lround( vdPar[5]) ; // P07
// 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) ;
// salvo spessore
m_dFcDepth = dDepth ;
// salvo flag di svuotatura
m_bFcPocket = ( nPocket == 1) ;
}
// 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, dAng, nProcId, nNextId) ;
// se previsto un prossimo punto, continuo
if ( nNextId != 0)
return true ;
// costruisco il contorno libero
PtrOwner<ICurveComposite> pCrvCompo( CurveFromFces( m_FcData)) ;
m_FcData.clear() ;
if ( IsNull( pCrvCompo))
return false ;
// se previsto, imposto spessore
pCrvCompo->SetThickness( -m_dFcDepth) ;
// 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 = IsPointNearFaceContour( ptStart, nSide) &&
IsPointNearFaceContour( ptEnd, nSide) ;
if ( ! bClosed && bEndsOnCont) {
if ( ! IsPointOnFaceContour( ptStart, nSide)) {
SetPointOnFaceContour( ptStart, nSide) ;
pCrvCompo->ModifyStart( ptStart) ;
}
if ( ! IsPointOnFaceContour( ptEnd, nSide)) {
SetPointOnFaceContour( ptEnd, nSide) ;
pCrvCompo->ModifyEnd( ptEnd) ;
}
}
// 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() ;
// se chiusa e con flag di svuotatura
if ( bClosed && m_bFcPocket) {
// creo la superficie di fondo
PtrOwner<ISurfTriMesh> pPocket( CreateSurfTriMesh()) ;
if ( IsNull( pPocket) || ! pPocket->CreateByFlatContour( PL))
return false ;
// la oriento correttamente
Vector3d vtN ;
if ( pPocket->GetFacetNormal( 0, vtN) && vtExtr * vtN < 0)
pPocket->Invert() ;
// la porto in posizione corretta
pPocket->Translate( vtExtr * dThick) ;
// la unisco alla parte laterale
pStm->DoSewing( *pPocket) ;
}
// 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) ;
// segnalo se svuotatura
if ( bClosed && m_bFcPocket)
m_pGDB->SetInfo( nId, IKEY_POCKET, 1) ;
// attributi utente
SetUserAttributes( nId, vsUAtt) ;
// identificativi di geometrie ausiliarie
SetAuxId( nId, {nTId}) ;
// aggiusto l'outline se spessore come trave
if ( UseProcessToTrimOutline( nId) && ((( bEndsOnCont || bClosed) && bHCross) || ( bClosed && m_bFcPocket)))
TrimOutline( nId) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::CreatePolygonInBox( const Point3d& ptP, const Vector3d& vtN, int nSide, Polygon3d& Polyg, double dMinDim)
{
// calcolo il piano
Plane3d plPlane ;
if ( ! plPlane.Set( ptP, vtN))
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)
if ( ! Polyg.FromPlaneTrimmedWithBox( plPlane, ORIG, ORIG + m_vtDim))
return false ;
// verifico che il materiale lasciato non sia inferiore al minimo
for ( int nS = BTL_SIDE_FRONT ; nS < BTL_SIDE_LEFT ; ++ nS) {
// confronto con ogni faccia del box della trave quasi opposta
Plane3d plFace = GetSidePlane( nS) ;
if ( plPlane.GetVersN() * plFace.GetVersN() < -0.5) {
// cerco minima profondit negativa
PNTVECTOR vVert = Polyg.GetVertices() ;
double dMinDist = 0 ;
for ( const auto& ptV : vVert) {
double dDist = DistPointPlane( ptV, plFace) ;
if ( dDist < dMinDist)
dMinDist = dDist ;
}
// se profondit non sufficicente, allora elimino la faccia
if ( dMinDist > - abs( dMinDim)) {
Polyg.Clear() ;
break ;
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::TrimPolygons( Polygon3d& plyP1, Polygon3d& plyP2, bool bInVsOut, bool bOnEq)
{
return ( plyP1.Trim( plyP2, bInVsOut, bOnEq) && plyP2.Trim( plyP1, bInVsOut, bOnEq)) ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::VerifyPolygon( Polygon3d& plyP, double dMinDim)
{
if ( ! plyP.IsValid())
return false ;
PolyLine PL = plyP.GetPolyLine() ;
double dPerim ; PL.GetLength( dPerim) ;
double dArea ; Plane3d plPla ; PL.IsClosedAndFlat( plPla, dArea, 10 * EPS_SMALL) ;
if ( 2 * dArea / dPerim >= dMinDim)
return true ;
plyP.Clear() ;
return false ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::VerifyPolygonWithPolygon( Polygon3d& plyP, const Polygon3d& plyRef, bool bInVsOut, double dMinDim)
{
// verifico sui poligoni
if ( ! plyP.IsValid())
return false ;
if ( ! plyRef.IsValid())
return true ;
// controllo soglia
dMinDim = max( dMinDim, EPS_SMALL) ;
// Se richiesto interno, verifico che il poligono stia dentro almeno della quantit minima
if ( bInVsOut) {
double dMinDist = INFINITO ;
for ( auto& ptV : plyP.GetVertices()) {
double dDist = DistPointPlane( ptV, plyRef.GetPlane()) ;
if ( dDist < dMinDist)
dMinDist = dDist ;
}
return ( dMinDist <= -dMinDim) ;
}
// altrimenti richiesto esterno, verifico che il poligono stia fuori almeno della quantit minima
else {
double dMaxDist = -INFINITO ;
for ( auto& ptV : plyP.GetVertices()) {
double dDist = DistPointPlane( ptV, plyRef.GetPlane()) ;
if ( dDist > dMaxDist)
dMaxDist = dDist ;
}
return ( dMaxDist >= dMinDim) ;
}
}
//----------------------------------------------------------------------------
bool
BtlGeom::VerifyPolygonWithPolygons( Polygon3d& plyP,
const Polygon3d& plyRef1, const Polygon3d& plyRef2,
bool bInVsOut, double dMinDim)
{
return ( VerifyPolygonWithPolygon( plyP, plyRef1, bInVsOut, dMinDim) &&
VerifyPolygonWithPolygon( plyP, plyRef2, bInVsOut, dMinDim)) ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::VerifyPolygonWithPolygons( Polygon3d& plyP,
const Polygon3d& plyRef1, const Polygon3d& plyRef2, const Polygon3d& plyRef3,
bool bInVsOut, double dMinDim)
{
return ( VerifyPolygonWithPolygon( plyP, plyRef1, bInVsOut, dMinDim) &&
VerifyPolygonWithPolygon( plyP, plyRef2, bInVsOut, dMinDim) &&
VerifyPolygonWithPolygon( plyP, plyRef3, bInVsOut, dMinDim)) ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::VerifyPolygonWithPolygons( Polygon3d& plyP,
const Polygon3d& plyRef1, const Polygon3d& plyRef2,
const Polygon3d& plyRef3, const Polygon3d& plyRef4,
bool bInVsOut, double dMinDim)
{
return ( VerifyPolygonWithPolygon( plyP, plyRef1, bInVsOut, dMinDim) &&
VerifyPolygonWithPolygon( plyP, plyRef2, bInVsOut, dMinDim) &&
VerifyPolygonWithPolygon( plyP, plyRef3, bInVsOut, dMinDim) &&
VerifyPolygonWithPolygon( plyP, plyRef4, bInVsOut, dMinDim)) ;
}
//----------------------------------------------------------------------------
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( ICurve* pCurve)
{
// verifico esistenza curva
if ( pCurve == nullptr)
return false ;
// determino il piano della curva
Plane3d plPlane ;
if ( ! pCurve->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( *pCurve, 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 ( ! pCurve->IsClosed()) {
// considero solo min-max degli intervalli
if ( inOk.GetCount() >= 1) {
// eseguo il taglio
double dParS, dParE ;
inOk.GetMinMax( dParS, dParE) ;
return pCurve->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 pCurve->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 ;
pCurve->GetDomain( dStart, dEnd) ;
double dParS1, dParE1 ;
inOk.GetFirst( dParS1, dParE1) ;
double dParS2, dParE2 ;
inOk.GetNext( dParS2, dParE2) ;
if ( abs( dParS1 - dStart) < EPS_SMALL && abs( dParE2 - dEnd) < EPS_SMALL)
return pCurve->TrimStartEndAtParam( dParS2, dParE1) ;
}
}
return false ;
}
//----------------------------------------------------------------------------
bool
BtlGeom::TrimSegmentWithBox( Point3d& ptP1, Point3d& ptP2, double dRad)
{
// eseguo trim con le facce della trave
for ( int i = BTL_SIDE_FRONT ; i <= BTL_SIDE_LEFT ; ++ i) {
// piano della faccia
Plane3d plFace = GetSidePlane( i) ;
// distanza con segno dei punti dal piano
double dDist1 = DistPointPlane( ptP1, plFace) ;
double dDist2 = DistPointPlane( ptP2, plFace) ;
// se entrambi esterni di pi del raggio, segmento da annullare
if ( dDist1 > dRad + EPS_SMALL && dDist2 > dRad + EPS_SMALL)
return false ;
// se primo esterno, devo spostare inizio
if ( dDist1 > EPS_SMALL)
ptP1 = Media( ptP1, ptP2, dDist1 / ( dDist1 + abs( dDist2))) ;
// se secondo esterno, devo spostare fine
else if ( dDist2 > EPS_SMALL)
ptP2 = Media( ptP2, ptP1, dDist2 / ( dDist2 + abs( dDist1))) ;
}
return true ;
}
//----------------------------------------------------------------------------
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 ;
// 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 e setto la retta
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
if ( IsNull( pCrvLine) || ! 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 e setto l'arco (se i punti sono allineati un segmento di retta)
PtrOwner<ICurve> pCrv ;
if ( ! pCrv.Set( GetArc3P( dqFce[i-1].ptP, dqFce[i].ptM, dqFce[i].ptP, false)))
return nullptr ;
// inserisco l'arco nella curva composta
if ( ! pCrvCompo->AddCurve( Release( pCrv)))
return nullptr ;
}
// altrimenti curva terminata
else
break ;
}
// imposto versore estrusione
pCrvCompo->SetExtrusion( Z_AX) ;
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, const STRVECTOR& vsUAtt)
{
if ( nId == GDB_ID_NULL)
return false ;
// elenco dei parametri
int nNumPar = min( int( vnDPar.size()), int( vdPar.size())) ;
for ( int i = 0 ; i < nNumPar ; ++ i) {
string sKey = IKEY_PAR + ToString( vnDPar[i], 2) ;
m_pGDB->SetInfo( nId, sKey, vdPar[i]) ;
}
// elenco degli eventuali attributi utente
return SetUserAttributes( nId, vsUAtt) ;
}
//---------------------------------------------------------------------------
bool
BtlGeom::SetUserAttributes( int nId, const STRVECTOR& vsUAtt)
{
if ( nId == GDB_ID_NULL)
return false ;
// elenco degli eventuali attributi utente
for ( const auto& sUAtt : vsUAtt) {
string sKey, sVal ;
if ( ReadUserAttribute( sUAtt, sKey, sVal)) {
// salvo nelle note
m_pGDB->SetInfo( nId, sKey, sVal) ;
// se disabilitazione, cambio colore
if (sKey == "DO" && sVal == "0") {
Color cCol ;
m_pGDB->GetCalcMaterial( nId, cCol) ;
cCol.Set( 160, 160, 160, cCol.GetIntAlpha()) ;
m_pGDB->SetMaterial( nId, cCol) ;
}
}
}
return true ;
}
//---------------------------------------------------------------------------
bool
BtlGeom::SetAuxId( int nId, const INTVECTOR& vnAuxId)
{
if ( nId == GDB_ID_NULL)
return false ;
// inserisco chiave con spiazzamento Id di geometrie ausiliarie
string sInfo ;
for ( auto nAuxId : vnAuxId) {
if ( nAuxId >= nId)
sInfo += "+" + ToString( nAuxId - nId) + "," ;
else
sInfo += ToString( nAuxId - nId) + "," ;
}
if ( ! sInfo.empty())
sInfo.pop_back() ;
m_pGDB->SetInfo( nId, IKEY_AUXID, sInfo) ;
return true ;
}
//---------------------------------------------------------------------------
bool
BtlGeom::SetDrillEnds( int nId, int nStartFace, int nEndFace)
{
if ( nId == GDB_ID_NULL)
return false ;
// inserisco chiavi con indice facce di inizio/fine foro
m_pGDB->SetInfo( nId, IKEY_START_FACE, nStartFace) ;
m_pGDB->SetInfo( nId, IKEY_END_FACE, nEndFace) ;
return true ;
}