Compare commits
174 Commits
SaraP
...
3dm_import
| Author | SHA1 | Date | |
|---|---|---|---|
| e2eb219c5a | |||
| e44b08d669 | |||
| 9b34154a16 | |||
| 10dd5828ce | |||
| bf2a3f0e22 | |||
| 38146c6294 | |||
| eccf683ef4 | |||
| 381a137604 | |||
| e5ed9efdd1 | |||
| 1ec38952ed | |||
| 0eb19f1735 | |||
| 737f4f4ffa | |||
| 8a81c3543e | |||
| c0fe5f14a8 | |||
| 9fce0bd4f4 | |||
| 663784a841 | |||
| 238c0ae490 | |||
| c4a4da6945 | |||
| fb62c6d68e | |||
| 2ba32eb93c | |||
| 6e34ab6169 | |||
| 538126cfe5 | |||
| a0a6bf8377 | |||
| ba05c5307a | |||
| 234878388d | |||
| baac48f7b9 | |||
| e4815830cd | |||
| b5b48bf4c2 | |||
| 8f84f78b16 | |||
| 8a3d46416d | |||
| c4f1a7f97b | |||
| 0c1ad4dd86 | |||
| 36547c24c2 | |||
| 3d4042e274 | |||
| b9a8777b96 | |||
| 6cf009fae3 | |||
| 735c12bca7 | |||
| 393cac35c5 | |||
| 804a434e75 | |||
| 71ba650cc5 | |||
| 0a63a4c9a2 | |||
| b78212c3a1 | |||
| 8420edecb5 | |||
| 7c6ddf2a6f | |||
| 2d8c815032 | |||
| 7023d721f4 | |||
| 0f530271f0 | |||
| ec3389633c | |||
| 5c0848797c | |||
| 545e37b7cd | |||
| 469e660da0 | |||
| 13b02f51a3 | |||
| d1790d8f07 | |||
| c925c6a17a | |||
| 00ccfe967e | |||
| 3b5d145f85 | |||
| ee4592a113 | |||
| 35618b1882 | |||
| bde7ff1e5c | |||
| 10f73435bf | |||
| 21b4af444b | |||
| 4410a83631 | |||
| ca19f9e735 | |||
| aa8ae0146d | |||
| 29138a63c8 | |||
| 64a904b628 | |||
| c939a50a39 | |||
| 27f28b9f28 | |||
| 053410f43b | |||
| a74949c832 | |||
| f84aefc82d | |||
| 133b590e1c | |||
| 65909b3366 | |||
| 68800a1dfa | |||
| 4f60bd24b6 | |||
| 2f3a6189a7 | |||
| 078f730512 | |||
| 368bd80c69 | |||
| e01941644b | |||
| 0f3bd716a3 | |||
| 0030b684f3 | |||
| 6e6be4e579 | |||
| 3add582efb | |||
| bd80f16812 | |||
| ffc78b03a7 | |||
| 2f6a1f7579 | |||
| e890d5f376 | |||
| 56b49d4c9f | |||
| 7ee0e38cec | |||
| 817bfa788e | |||
| a4bd5a25c2 | |||
| 7c3b3e516a | |||
| 9e3c8b697a | |||
| 775fec489b | |||
| 790a75054c | |||
| b57421e2c9 | |||
| a7dea8b1db | |||
| 2808a95e4a | |||
| e0a350b148 | |||
| 560a447349 | |||
| 700b2ad5ca | |||
| 85d677a41a | |||
| cc200501e9 | |||
| d59cb55139 | |||
| 46052e9d1f | |||
| b36baf0fab | |||
| f2499d08ba | |||
| 651b34781b | |||
| c57a6db4ae | |||
| 78b9234865 | |||
| 6238ea1095 | |||
| de99955e93 | |||
| c45912a2e4 | |||
| 025b4a8b48 | |||
| a5802f0731 | |||
| 4f0a1460fd | |||
| 498e5b37f4 | |||
| fe0a6ad15d | |||
| 13774ba26a | |||
| d1b22114d0 | |||
| 3f2b6b2115 | |||
| bb8c0f766e | |||
| 76e490a583 | |||
| ae91e1c51f | |||
| 4aff949349 | |||
| 3dcceecab7 | |||
| 7b6f1c3e92 | |||
| b107596f84 | |||
| b11de227f3 | |||
| f353e65e61 | |||
| de34cfb7e8 | |||
| cb882b9379 | |||
| f43951a9e2 | |||
| 899e371c52 | |||
| 555e0e4375 | |||
| 8710115634 | |||
| 4056be90d9 | |||
| 77640f3a6f | |||
| 9b11212d07 | |||
| 41d76f0c3f | |||
| d2b77833fd | |||
| 9ac1a56535 | |||
| 9aca1f1e25 | |||
| e3c10e9bd3 | |||
| e84a34917a | |||
| 009328b31b | |||
| ca83aaa249 | |||
| 6cdfdf6db8 | |||
| 6628b1ee24 | |||
| 2d70d27d85 | |||
| 63d62fcc92 | |||
| b4303d0e0d | |||
| 9369447886 | |||
| dca713b240 | |||
| aa82c82ddc | |||
| 8a6dbf044e | |||
| 76d009ddbe | |||
| 6deff01b6e | |||
| e79bb117d2 | |||
| 2ea4b59b9b | |||
| 6e9465247f | |||
| 1d1fb41212 | |||
| add949b6a6 | |||
| 4731df3702 | |||
| e7d0b00e0f | |||
| 641708a5fa | |||
| f5b11a61a0 | |||
| a4cc43dadb | |||
| 334ce10018 | |||
| 3d233597f3 | |||
| a5fad89380 | |||
| d0f9c2fff5 | |||
| 038142a6d7 | |||
| 26424252f9 |
+90
-27
@@ -15,15 +15,30 @@
|
||||
#include "stdafx.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "RemoveCurveSpikes.h"
|
||||
#include "RemoveCurveDefects.h"
|
||||
#include "AdjustLoops.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//-------------------------------------------------------
|
||||
static bool
|
||||
SortCrvCrvInfo( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2)
|
||||
{
|
||||
// confronto i valori del primo punto della curva A
|
||||
double dU1 = aInfo1.IciA[0].dU ;
|
||||
double dU2 = aInfo2.IciA[0].dU ;
|
||||
if ( abs( dU1 - dU2) < EPS_SMALL)
|
||||
// se sono uguali confronto i valori del primo punto della curva B
|
||||
return aInfo1.IciB[0].dU > aInfo2.IciB[0].dU ;
|
||||
else
|
||||
return dU1 < dU2 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
@@ -73,43 +88,75 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
return false ;
|
||||
Intervals inOk( EPS_PARAM) ;
|
||||
inOk.Set( dStart, dEnd) ;
|
||||
|
||||
// Tolgo le parti da eliminare
|
||||
|
||||
// recupero tutte le info delle autointersezioni
|
||||
IntCrvCrvInfo iccInfo ;
|
||||
for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i) {
|
||||
ICCIVECTOR vIccInfo( sintC.GetIntersCount()) ;
|
||||
for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i)
|
||||
vIccInfo[i]= iccInfo ;
|
||||
// ordino il vettore
|
||||
sort( vIccInfo.begin(), vIccInfo.end(), SortCrvCrvInfo) ;
|
||||
|
||||
// Tolgo le parti da eliminare
|
||||
int nCross = 0 ;
|
||||
for ( int i = 0 ; i < int( vIccInfo.size()) ; ++ i) {
|
||||
|
||||
if ( i < int( vIccInfo.size()) - 1) {
|
||||
// se anche l'intersezione successiva è overlap che parte dallo stesso punto
|
||||
if ( vIccInfo[i].bOverlap && vIccInfo[i+1].bOverlap &&
|
||||
abs( vIccInfo[i].IciA[0].dU - vIccInfo[i+1].IciA[0].dU) < EPS_SMALL &&
|
||||
abs( vIccInfo[i].IciB[0].dU - vIccInfo[i+1].IciB[0].dU) < EPS_SMALL) {
|
||||
// elimino il tratto
|
||||
inOk.Subtract( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciB[0].dU) ;
|
||||
// salto le intersezioni successive già considerate rimuovendo questo intervallo
|
||||
int j = i + 2 ;
|
||||
while ( j < ( int)vIccInfo.size() && vIccInfo[j].IciA[0].dU > vIccInfo[i].IciA[0].dU - EPS_SMALL &&
|
||||
vIccInfo[j].IciA[1].dU < vIccInfo[i].IciB[0].dU + EPS_SMALL) {
|
||||
j ++ ;
|
||||
}
|
||||
// aggiorno il contatore
|
||||
i = j - 1 ;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
|
||||
// se con sovrapposizione
|
||||
if ( iccInfo.bOverlap) {
|
||||
if ( vIccInfo[i].bOverlap) {
|
||||
// se solo touch
|
||||
if ( ( iccInfo.IciA[0].nPrevTy == iccInfo.IciA[1].nNextTy ||
|
||||
iccInfo.IciA[0].nPrevTy == ICCT_SPK || iccInfo.IciA[1].nNextTy == ICCT_SPK) &&
|
||||
iccInfo.IciA[0].nPrevTy != ICCT_NULL && iccInfo.IciA[1].nNextTy != ICCT_NULL) {
|
||||
if ( ( vIccInfo[i].IciA[0].nPrevTy == vIccInfo[i].IciA[1].nNextTy ||
|
||||
vIccInfo[i].IciA[0].nPrevTy == ICCT_SPK || vIccInfo[i].IciA[1].nNextTy == ICCT_SPK) &&
|
||||
vIccInfo[i].IciA[0].nPrevTy != ICCT_NULL && vIccInfo[i].IciA[1].nNextTy != ICCT_NULL) {
|
||||
// obbligatoriamente controversi, elimino entrambi i tratti
|
||||
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[1].dU) ;
|
||||
inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ;
|
||||
inOk.Subtract( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciA[1].dU) ;
|
||||
inOk.Subtract( vIccInfo[i].IciB[0].dU, vIccInfo[i].IciB[1].dU) ;
|
||||
}
|
||||
// altrimenti attraversamento
|
||||
else {
|
||||
// elimino la parte interna
|
||||
if ( iccInfo.bCBOverEq)
|
||||
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciB[0].dU) ;
|
||||
if ( vIccInfo[i].bCBOverEq)
|
||||
inOk.Subtract( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciB[0].dU) ;
|
||||
else
|
||||
inOk.Subtract( min( iccInfo.IciA[0].dU, iccInfo.IciB[1].dU), max( iccInfo.IciB[0].dU, iccInfo.IciA[1].dU)) ;
|
||||
inOk.Subtract( min( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciB[1].dU), max( vIccInfo[i].IciB[0].dU, vIccInfo[i].IciA[1].dU)) ;
|
||||
}
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
// se solo touch
|
||||
if ( iccInfo.IciA[0].nPrevTy == iccInfo.IciA[0].nNextTy &&
|
||||
iccInfo.IciA[0].nPrevTy != ICCT_NULL && iccInfo.IciA[0].nNextTy != ICCT_NULL) {
|
||||
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[0].dU) ;
|
||||
inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[0].dU) ;
|
||||
if ( vIccInfo[i].IciA[0].nPrevTy == vIccInfo[i].IciA[0].nNextTy &&
|
||||
vIccInfo[i].IciA[0].nPrevTy != ICCT_NULL && vIccInfo[i].IciA[0].nNextTy != ICCT_NULL) {
|
||||
inOk.Subtract( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciA[0].dU) ;
|
||||
inOk.Subtract( vIccInfo[i].IciB[0].dU, vIccInfo[i].IciB[0].dU) ;
|
||||
}
|
||||
// altrimenti attraversamento
|
||||
else {
|
||||
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciB[0].dU) ;
|
||||
if ( IsEven( nCross))
|
||||
inOk.Subtract( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciB[0].dU) ;
|
||||
else
|
||||
inOk.Add( vIccInfo[i].IciA[0].dU, vIccInfo[i].IciB[0].dU) ;
|
||||
++ nCross ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copio le parti da conservare
|
||||
double dParS, dParE ;
|
||||
@@ -179,14 +226,14 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
Point3d ptEnd2 ; pCrvCo2->GetEndPoint( ptEnd2) ;
|
||||
// se aperta, verifico se concatenabile alla principale
|
||||
if ( ! AreSamePointEpsilon( ptStart2, ptEnd2, 10 * EPS_SMALL)) {
|
||||
if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL)) {
|
||||
pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL) ;
|
||||
if ( AreSamePointEpsilon( ptEnd, ptStart2, 100 * EPS_SMALL)) {
|
||||
pCrvCo->AddCurve( pCrvCo2, true, 100 * EPS_SMALL) ;
|
||||
CrvLst.erase( iIter2) ;
|
||||
ptEnd = ptEnd2 ;
|
||||
iIter2 = next( iIter) ;
|
||||
}
|
||||
else if ( AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) {
|
||||
pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL) ;
|
||||
else if ( AreSamePointEpsilon( ptEnd2, ptStart, 100 * EPS_SMALL)) {
|
||||
pCrvCo->AddCurve( pCrvCo2, false, 100 * EPS_SMALL) ;
|
||||
CrvLst.erase( iIter2) ;
|
||||
ptStart = ptStart2 ;
|
||||
iIter2 = next( iIter) ;
|
||||
@@ -201,6 +248,22 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
++ iIter ;
|
||||
}
|
||||
|
||||
// elimino le curve troppo piccole
|
||||
for ( auto iIter = CrvLst.begin() ; iIter != CrvLst.end() ;) {
|
||||
CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
|
||||
BBox3d b3CrvCo ;
|
||||
double dDiam ;
|
||||
if ( ! pCrvCo->GetLocalBBox( b3CrvCo) || b3CrvCo.IsEmpty() ||
|
||||
! b3CrvCo.GetDiameter( dDiam) || dDiam < 20 * EPS_SMALL) {
|
||||
delete pCrvCo ;
|
||||
pCrvCo = nullptr ;
|
||||
iIter = CrvLst.erase( iIter) ;
|
||||
}
|
||||
else {
|
||||
++ iIter ;
|
||||
}
|
||||
}
|
||||
|
||||
// riporto le curve nel riferimento originale
|
||||
if ( bNeedRef) {
|
||||
for ( auto pCrv : CrvLst)
|
||||
@@ -215,7 +278,7 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst, bool bNeedSameProp)
|
||||
{
|
||||
// elimino eventuali sovrapposizioni e accostamenti
|
||||
if ( ! MyAdjustLoops( pCurve, CrvLst))
|
||||
@@ -225,10 +288,10 @@ AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
// se curva composita
|
||||
CurveComposite* pCrvCo = GetBasicCurveComposite( pCrv) ;
|
||||
if ( pCrvCo != nullptr) {
|
||||
// elimino eventuali Spikes e Small Z
|
||||
pCrvCo->RemoveSmallDefects( 2 * LIN_TOL_MIN, ANG_TOL_STD_DEG, true) ;
|
||||
// unisco eventuali tratti allineati
|
||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
||||
// elimino eventuali spikes
|
||||
RemoveCurveSpikes( pCrvCo) ;
|
||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, bNeedSameProp) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -17,4 +17,4 @@
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst) ;
|
||||
bool AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst, bool bNeedSameProp) ;
|
||||
|
||||
@@ -63,3 +63,57 @@ AngleInSpan( double dAngDeg, double dAngRefDeg, double dAngSpanDeg)
|
||||
dAngDiffDeg < dHalfAngSpanDeg + EPS_ANG_SMALL) ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
AngleInRange( double dAngDeg, double dAngMinDeg, double dAngMaxDeg)
|
||||
{
|
||||
return AngleInSpan( dAngDeg, ( dAngMinDeg + dAngMaxDeg) / 2, dAngMaxDeg - dAngMinDeg) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
AdjustAngleInSpan( double& dAngDeg, double dAngRefDeg, double dAngSpanDeg)
|
||||
{
|
||||
// Verifico consistenza intervallo
|
||||
if ( dAngSpanDeg < -EPS_ANG_ZERO)
|
||||
return false ;
|
||||
// Se intervallo vero
|
||||
if ( dAngSpanDeg > EPS_ANG_SMALL) {
|
||||
double dTryDeg = dAngDeg ;
|
||||
// eseguo gli aggiustamenti
|
||||
while ( dTryDeg < dAngRefDeg - dAngSpanDeg)
|
||||
dTryDeg += ANG_FULL ;
|
||||
while ( dTryDeg > dAngRefDeg + dAngSpanDeg)
|
||||
dTryDeg -= ANG_FULL ;
|
||||
// verifico
|
||||
if ( dTryDeg >= dAngRefDeg - dAngSpanDeg && dTryDeg <= dAngRefDeg + dAngSpanDeg) {
|
||||
dAngDeg = dTryDeg ;
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
// altrimenti un valore
|
||||
else {
|
||||
double dTryDeg = dAngDeg ;
|
||||
// eseguo gli aggiustamenti
|
||||
while ( dTryDeg < dAngRefDeg - EPS_ANG_SMALL)
|
||||
dTryDeg += ANG_FULL ;
|
||||
while ( dTryDeg > dAngRefDeg + EPS_ANG_SMALL)
|
||||
dTryDeg -= ANG_FULL ;
|
||||
// verifico
|
||||
if ( abs( dTryDeg - dAngRefDeg) < EPS_ANG_SMALL) {
|
||||
dAngDeg = dAngRefDeg ;
|
||||
return true ;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
AdjustAngleInRange( double& dAngDeg, double dAngMinDeg, double dAngMaxDeg)
|
||||
{
|
||||
return AdjustAngleInSpan( dAngDeg, ( dAngMinDeg + dAngMaxDeg) / 2, dAngMaxDeg - dAngMinDeg) ;
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
#include "CurveComposite.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkArcCenTgCurvePnt.h"
|
||||
#include "/EgtDev/Include/EgkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EgkCircleCenTgCurve.h"
|
||||
#include "/EgtDev/Include/EgkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkArcCenTgCurvePnt.h"
|
||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EGkCircleCenTgCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ CurveArc* GetArcCenTgCompoPnt( const Point3d& ptCen, const CurveComposite& crvCo
|
||||
double dSqDist = SqDist( ptNearStart, ptTg) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvArc.Set( Release( pCrvAtmp)) ;
|
||||
pCrvArc.Set( pCrvAtmp) ;
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkArcPntDirTgCurve.h"
|
||||
#include "/EgtDev/Include/EgkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EGkArcPntDirTgCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ GetArcPntDirTgArc( const Point3d& ptP, const Vector3d& vtDir, const CurveArc& cr
|
||||
if ( bOk1) {
|
||||
double dOffset = ( bOutSide ? crvArcL.GetRadius() : - crvArcL.GetRadius()) ;
|
||||
if ( pCrv1->GetType() == CRV_ARC)
|
||||
bOk1 = (dynamic_cast<CurveArc*>(Get(pCrv1)))->ExtendedOffset( dOffset) ;
|
||||
bOk1 = (static_cast<CurveArc*>( Get( pCrv1)))->ExtendedOffset( dOffset) ;
|
||||
else
|
||||
bOk1 = pCrv1->SimpleOffset( dOffset) ;
|
||||
}
|
||||
@@ -235,7 +235,7 @@ GetArcPntDirTgArc( const Point3d& ptP, const Vector3d& vtDir, const CurveArc& cr
|
||||
if ( bOk2) {
|
||||
double dOffset = ( bOutSide ? - crvArcL.GetRadius() : crvArcL.GetRadius()) ;
|
||||
if ( pCrv2->GetType() == CRV_ARC)
|
||||
bOk2 = (dynamic_cast<CurveArc*>(Get(pCrv2)))->ExtendedOffset( dOffset) ;
|
||||
bOk2 = (static_cast<CurveArc*>( Get( pCrv2)))->ExtendedOffset( dOffset) ;
|
||||
else
|
||||
bOk2 = pCrv2->SimpleOffset( dOffset) ;
|
||||
}
|
||||
@@ -337,7 +337,7 @@ GetArcPntDirTgCompo( const Point3d& ptP, const Vector3d& vtDir, const CurveCompo
|
||||
double dSqDist = SqDist( ptNear, ptTg) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvNew.Set( Release( pCrvTmp)) ;
|
||||
pCrvNew.Set( pCrvTmp) ;
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
}
|
||||
|
||||
+86
-36
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2015
|
||||
// EgalTech 2014-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ArcSpecial.cpp Data : 15.03.15 Versione : 1.6c2
|
||||
// File : ArcSpecial.cpp Data : 04.08.23 Versione : 2.5h1
|
||||
// Contenuto : Implementazione funzioni per calcoli speciali archi.
|
||||
//
|
||||
//
|
||||
@@ -14,13 +14,12 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "/EgtDev/Include/EgkCurveLine.h"
|
||||
#include "/EgtDev/Include/EgkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EGkCurveLine.h"
|
||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Come la CurveArc::Set2PD, ma se raggio infinito restituisce una retta
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -28,15 +27,13 @@ ICurve*
|
||||
GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
ICurveArc* pArc = CreateCurveArc() ;
|
||||
if ( pArc == nullptr)
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pArc))
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con l'arco
|
||||
PtrOwner<ICurve> pCrv( pArc) ;
|
||||
|
||||
// calcolo l'arco, se ok lo restituisco ed esco
|
||||
if ( pArc->Set2PD( ptStart, ptEnd, dDirStartDeg))
|
||||
return Release( pCrv) ;
|
||||
return Release( pArc) ;
|
||||
|
||||
// calcolo arco non riuscito, verifico se retta va bene
|
||||
Vector3d vtDiff = ptEnd - ptStart ;
|
||||
@@ -45,14 +42,12 @@ GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg)
|
||||
// verifico se i punti sono allineati con la direzione e nel giusto verso
|
||||
if ( abs( CrossXY( vtDiff, vtDir)) < EPS_SMALL && ScalarXY( vtDiff, vtDir) > EPS_SMALL) {
|
||||
// creo l'oggetto retta
|
||||
ICurveLine* pLine = CreateCurveLine() ;
|
||||
if ( pLine == nullptr)
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pLine))
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con la retta
|
||||
pCrv.Set( pLine) ;
|
||||
// calcolo retta, se ok la restituisco ed esco
|
||||
if ( pLine->Set( ptStart, ptEnd))
|
||||
return Release( pCrv) ;
|
||||
return Release( pLine) ;
|
||||
}
|
||||
|
||||
return nullptr ;
|
||||
@@ -65,34 +60,59 @@ ICurve*
|
||||
GetArc2PVN( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDirS, const Vector3d& vtN)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
ICurveArc* pArc = CreateCurveArc() ;
|
||||
if ( pArc == nullptr)
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pArc))
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con l'arco
|
||||
PtrOwner<ICurve> pCrv( pArc) ;
|
||||
|
||||
// calcolo l'arco, se ok lo restituisco ed esco
|
||||
if ( pArc->Set2PVN( ptStart, ptEnd, vtDirS, vtN))
|
||||
return Release( pCrv) ;
|
||||
return Release( pArc) ;
|
||||
|
||||
// calcolo arco non riuscito, verifico se retta va bene
|
||||
Vector3d vtDiff = ptEnd - ptStart ;
|
||||
// verifico se i punti sono allineati con la direzione e nel giusto verso nel piano perpendicolare a vtN
|
||||
if ( abs( ( vtDiff ^ vtDirS) * vtN) < EPS_SMALL && vtDiff * vtDirS > EPS_SMALL) {
|
||||
// creo l'oggetto retta
|
||||
ICurveLine* pLine = CreateCurveLine() ;
|
||||
if ( pLine == nullptr)
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pLine))
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con la retta
|
||||
pCrv.Set( pLine) ;
|
||||
// calcolo retta, se ok la restituisco ed esco
|
||||
if ( pLine->Set( ptStart, ptEnd))
|
||||
return Release( pCrv) ;
|
||||
return Release( pLine) ;
|
||||
}
|
||||
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Come la CurveArc::Set2PNB, ma se bulge nullo restituisce una retta
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArc2PNB( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtN, double dBulge)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pArc))
|
||||
return nullptr ;
|
||||
|
||||
// calcolo l'arco, se ok lo restituisco ed esco
|
||||
if ( pArc->Set2PNB( ptStart, ptEnd, vtN, dBulge))
|
||||
return Release( pArc) ;
|
||||
|
||||
// calcolo arco non riuscito, verifico se retta va bene
|
||||
if ( abs( dBulge) > EPS_SMALL)
|
||||
return nullptr ;
|
||||
// creo l'oggetto retta
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pLine))
|
||||
return nullptr ;
|
||||
// calcolo retta, se ok la restituisco ed esco
|
||||
if ( pLine->Set( ptStart, ptEnd))
|
||||
return Release( pLine) ;
|
||||
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Come la CurveArc::Set3P, ma se raggio infinito restituisce una retta
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -100,17 +120,15 @@ ICurve*
|
||||
GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd, bool bCirc)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
ICurveArc* pArc = CreateCurveArc() ;
|
||||
if ( pArc == nullptr)
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pArc))
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con l'arco
|
||||
PtrOwner<ICurve> pCrv( pArc) ;
|
||||
|
||||
// calcolo l'arco, se ok lo restituisco ed esco
|
||||
if ( pArc->Set3P( ptStart, ptOther, ptEnd, bCirc))
|
||||
return Release( pCrv) ;
|
||||
return Release( pArc) ;
|
||||
|
||||
// se era richiesta una circonferenza, errore
|
||||
// se era richiesta una circonferenza, errore perchè punti allineati
|
||||
if ( bCirc)
|
||||
return nullptr ;
|
||||
|
||||
@@ -118,15 +136,47 @@ GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd,
|
||||
// verifico se i punti sono allineati nel giusto verso
|
||||
if ( ( ptOther - ptStart) * ( ptEnd - ptOther) > EPS_ZERO) {
|
||||
// creo l'oggetto retta
|
||||
ICurveLine* pLine = CreateCurveLine() ;
|
||||
if ( pLine == nullptr)
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pLine))
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con la retta
|
||||
pCrv.Set( pLine) ;
|
||||
// calcolo retta, se ok la restituisco ed esco
|
||||
if ( pLine->Set( ptStart, ptEnd))
|
||||
return Release( pCrv) ;
|
||||
return Release( pLine) ;
|
||||
}
|
||||
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Come la CurveArc::SetC2PN, ma garantisce il passaggio per gli estremi e minimizza errore sul centro
|
||||
//----------------------------------------------------------------------------
|
||||
ICurveArc*
|
||||
GetArc2PCN( const Point3d& ptStart, const Point3d& ptEnd, const Point3d& ptNearCen, const Vector3d& vtN)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pArc))
|
||||
return nullptr ;
|
||||
|
||||
// vettori dal centro a inizio e fine
|
||||
Vector3d vtStart = ptStart - ptNearCen ;
|
||||
Vector3d vtEnd = ptEnd - ptNearCen ;
|
||||
|
||||
// determino il raggio medio
|
||||
double dStartRad = OrthoCompo( vtStart, vtN).Len() ;
|
||||
double dEndRad = OrthoCompo( vtEnd, vtN).Len() ;
|
||||
double dRad = ( dStartRad + dEndRad) / 2 ;
|
||||
if ( dRad < EPS_SMALL)
|
||||
return nullptr ;
|
||||
|
||||
// determino un valore approssimato dell'angolo al centro
|
||||
double dAngDeg ; bool bDet ;
|
||||
if ( ! vtStart.GetRotation( vtEnd, vtN, dAngDeg, bDet) || ! bDet || abs( dAngDeg) < EPS_ANG_ZERO)
|
||||
return nullptr ;
|
||||
|
||||
// calcolo l'arco antiorario per i due punti con il raggio medio
|
||||
if ( pArc->Set2PNRS( ptStart, ptEnd, vtN, dRad, ( dAngDeg > 0)))
|
||||
return Release( pArc) ;
|
||||
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
+21
-3
@@ -18,7 +18,7 @@
|
||||
#include "NgeReader.h"
|
||||
#include "GeomDB.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EgnStringKeyVal.h"
|
||||
#include "/EgtDev/Include/EGnStringKeyVal.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -212,7 +212,7 @@ bool
|
||||
Attribs::SetName( const string& sName)
|
||||
{
|
||||
// se nome non valido, esco con errore
|
||||
if ( ! IsValidVal( sName))
|
||||
if ( sName.empty() || ! IsValidVal( sName))
|
||||
return false ;
|
||||
|
||||
// può essere solo la prima stringa
|
||||
@@ -282,7 +282,7 @@ bool
|
||||
Attribs::SetInfo( const string& sKey, const string& sVal)
|
||||
{
|
||||
// se chiave o valore non validi, esco con errore
|
||||
if ( ! IsValidKey( sKey) || ! IsValidVal( sVal))
|
||||
if ( ! IsValidKey( sKey) || sVal.empty() || ! IsValidVal( sVal))
|
||||
return false ;
|
||||
|
||||
// se è il nome
|
||||
@@ -356,6 +356,24 @@ Attribs::RemoveInfo( const string& sKey)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Attribs::GetAllInfo( STRVECTOR& vsInfo) const
|
||||
{
|
||||
// riservo spazio opportuno per il vettore delle stringhe
|
||||
vsInfo.clear() ;
|
||||
if ( (int) m_slInfo.size() == 0)
|
||||
return true ;
|
||||
vsInfo.reserve( m_slInfo.size()) ;
|
||||
// recupero tutte le info tranne il nome (se presente sempre al primo posto)
|
||||
auto iIter = m_slInfo.cbegin() ;
|
||||
if ( FindKey( *iIter, NAME))
|
||||
++ iIter ;
|
||||
for ( ; iIter != m_slInfo.cend() ; ++ iIter)
|
||||
vsInfo.emplace_back( *iIter) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Attribs::CopyAllInfoFrom( const Attribs& attrSou)
|
||||
|
||||
@@ -89,6 +89,7 @@ class Attribs
|
||||
bool GetInfo( const std::string& sKey, std::string& sVal) const ;
|
||||
bool ExistsInfo( const std::string& sKey) const ;
|
||||
bool RemoveInfo( const std::string& sKey) ;
|
||||
bool GetAllInfo( STRVECTOR& vsInfo) const ;
|
||||
bool CopyAllInfoFrom( const Attribs& attrSou) ;
|
||||
|
||||
private :
|
||||
@@ -100,7 +101,7 @@ class Attribs
|
||||
private :
|
||||
unsigned char m_Data[DIM] ;
|
||||
unsigned char m_OldData[DIM] ;
|
||||
int m_Material ;
|
||||
Color m_Color ;
|
||||
STRLIST m_slInfo ;
|
||||
int m_Material ;
|
||||
Color m_Color ;
|
||||
STRLIST m_slInfo ;
|
||||
} ;
|
||||
+134
-34
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2013
|
||||
// EgalTech 2014-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : BBox3d.cpp Data : 14.01.14 Versione : 1.5a3
|
||||
// File : BBox3d.cpp Data : 17.08.22 Versione : 2.4h1
|
||||
// Contenuto : Implementazione della classe axis aligned bounding box BBox3d.
|
||||
//
|
||||
//
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "\EgtDev\Include\EGkBBox3d.h"
|
||||
#include "\EgtDev\Include\EGkFrame3d.h"
|
||||
#include "/EgtDev/Include/EGkBBox3d.h"
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
@@ -53,7 +53,8 @@ BBox3d::Set( double dX1, double dY1, double dZ1, double dX2, double dY2, double
|
||||
bool
|
||||
BBox3d::IsValid( void) const
|
||||
{
|
||||
return ( m_ptMin.x < ( m_ptMax.x + EPS_SMALL) &&
|
||||
return ( m_ptMin.IsValid() && m_ptMax.IsValid() &&
|
||||
m_ptMin.x < ( m_ptMax.x + EPS_SMALL) &&
|
||||
m_ptMin.y < ( m_ptMax.y + EPS_SMALL) &&
|
||||
m_ptMin.z < ( m_ptMax.z + EPS_SMALL)) ;
|
||||
}
|
||||
@@ -210,6 +211,33 @@ BBox3d::GetMinDim( Point3d& ptMin, double& dDimX, double& dDimY, double& dDimZ)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
BBox3d::GetDimX( void) const
|
||||
{
|
||||
if ( ! IsValid())
|
||||
return 0 ;
|
||||
return ( m_ptMax.x - m_ptMin.x) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
BBox3d::GetDimY( void) const
|
||||
{
|
||||
if ( ! IsValid())
|
||||
return 0 ;
|
||||
return ( m_ptMax.y - m_ptMin.y) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
BBox3d::GetDimZ( void) const
|
||||
{
|
||||
if ( ! IsValid())
|
||||
return 0 ;
|
||||
return ( m_ptMax.z - m_ptMin.z) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::GetCenterExtent( Point3d& ptCenter, Vector3d& vtExtent) const
|
||||
@@ -420,69 +448,141 @@ BBox3d::EnclosesXY( const BBox3d& b3Box) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::Overlaps( const BBox3d& b3B) const
|
||||
BBox3d::Overlaps( const BBox3d& b3Box) const
|
||||
{
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
|
||||
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::OverlapsXY( const BBox3d& b3B) const
|
||||
BBox3d::OverlapsXY( const BBox3d& b3Box) const
|
||||
{
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::FindIntersection( const BBox3d& b3B, BBox3d& b3Int) const
|
||||
inline bool
|
||||
TestSeparatingAxis( const Vector3d& vtAx, const Vector3d& vtDiff, const Vector3d& vtHe,
|
||||
const Vector3d& vtHe2X, const Vector3d& vtHe2Y, const Vector3d& vtHe2Z)
|
||||
{
|
||||
if ( ! IsValid() || ! b3B.IsValid())
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
double dLen = ( vtAx.IsNormalized() ? 1 : vtAx.Len()) ;
|
||||
return ( abs( vtDiff * vtAx) >
|
||||
abs( vtHe.x * vtAx.x) + abs( vtHe.y * vtAx.y) + abs( vtHe.z * vtAx.z) +
|
||||
abs( vtHe2X * vtAx) + abs( vtHe2Y * vtAx) + abs( vtHe2Z * vtAx) + EPS_SMALL * dLen) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::Overlaps( const Frame3d& frBox, const BBox3d& b3Box) const
|
||||
{
|
||||
// Verifico validità di entrambi i box
|
||||
if ( ! IsValid() || ! b3Box.IsValid())
|
||||
return false ;
|
||||
|
||||
// Centro e semiampiezza del box
|
||||
Point3d ptCen = ( m_ptMin + m_ptMax) / 2 ;
|
||||
Vector3d vtHe = ( m_ptMax - m_ptMin) / 2 ;
|
||||
// Centro e semiampiezza dell'altro box
|
||||
Point3d ptCen2 = GetToGlob( ( b3Box.m_ptMin + b3Box.m_ptMax) / 2, frBox) ;
|
||||
Vector3d vtHe2X = GetToGlob( Vector3d( ( b3Box.GetDimX()) / 2, 0, 0), frBox) ;
|
||||
Vector3d vtHe2Y = GetToGlob( Vector3d( 0, ( b3Box.GetDimY()) / 2, 0), frBox) ;
|
||||
Vector3d vtHe2Z = GetToGlob( Vector3d( 0, 0, ( b3Box.GetDimZ()) / 2), frBox) ;
|
||||
// Vettore tra i due centri
|
||||
Vector3d vtDiff = ptCen2 - ptCen ;
|
||||
|
||||
// Verifico separazione sulle normali ai piani principali del riferimento globale
|
||||
if ( TestSeparatingAxis( X_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Y_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Z_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
|
||||
// Verifico separazione sulle normali ai piani principali del secondo riferimento
|
||||
if ( TestSeparatingAxis( frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
|
||||
// Verifico separazione sulle altre normali ottenute come prodotto vettoriali di quelle precedenti
|
||||
if ( TestSeparatingAxis( X_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( X_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( X_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Y_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Y_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Y_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Z_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Z_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
if ( TestSeparatingAxis( Z_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
||||
return false ;
|
||||
|
||||
// Si sovrappongono
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::FindIntersection( const BBox3d& b3Box, BBox3d& b3Int) const
|
||||
{
|
||||
if ( ! IsValid() || ! b3Box.IsValid())
|
||||
return false ;
|
||||
// verifico direttamente la sovrapposizione
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
|
||||
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
// calcolo il box intersezione
|
||||
b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ;
|
||||
b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
|
||||
b3Int.m_ptMin.z = (( m_ptMin.z >= b3B.m_ptMin.z) ? m_ptMin.z : b3B.m_ptMin.z) ;
|
||||
b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ;
|
||||
b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ;
|
||||
b3Int.m_ptMax.z = (( m_ptMax.z <= b3B.m_ptMax.z) ? m_ptMax.z : b3B.m_ptMax.z) ;
|
||||
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
|
||||
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
|
||||
b3Int.m_ptMin.z = (( m_ptMin.z >= b3Box.m_ptMin.z) ? m_ptMin.z : b3Box.m_ptMin.z) ;
|
||||
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
|
||||
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
|
||||
b3Int.m_ptMax.z = (( m_ptMax.z <= b3Box.m_ptMax.z) ? m_ptMax.z : b3Box.m_ptMax.z) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
BBox3d::FindIntersectionXY( const BBox3d& b3B, BBox3d& b3Int) const
|
||||
BBox3d::FindIntersectionXY( const BBox3d& b3Box, BBox3d& b3Int) const
|
||||
{
|
||||
if ( ! IsValid() || ! b3B.IsValid())
|
||||
if ( ! IsValid() || ! b3Box.IsValid())
|
||||
return false ;
|
||||
// verifico direttamente la sovrapposizione
|
||||
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
|
||||
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
|
||||
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
// calcolo il box intersezione
|
||||
b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ;
|
||||
b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
|
||||
b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3B.m_ptMin.z) ;
|
||||
b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ;
|
||||
b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ;
|
||||
b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3B.m_ptMax.z) ;
|
||||
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
|
||||
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
|
||||
b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3Box.m_ptMin.z) ;
|
||||
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
|
||||
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
|
||||
b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3Box.m_ptMax.z) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
+26
-14
@@ -16,10 +16,11 @@
|
||||
#include "BiArcs.h"
|
||||
#include "CurveArc.h"
|
||||
#include "/EgtDev/Include/EGkAngle.h"
|
||||
#include "/EgtDev/Include/EgkCurveLine.h"
|
||||
#include "/EgtDev/Include/EgkCurveComposite.h"
|
||||
#include "/EgtDev/Include/EgkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EGkCurveLine.h"
|
||||
#include "/EgtDev/Include/EGkCurveComposite.h"
|
||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
@@ -97,7 +98,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
CurveArc* pArc = GetBasicCurveArc( pJCrv) ;
|
||||
if ( pArc == nullptr)
|
||||
return nullptr ;
|
||||
double dU = - 1 ;
|
||||
double dU = -1 ;
|
||||
double dRad = pArc->GetRadius() ;
|
||||
double dSqRad = dRad * dRad ;
|
||||
Point3d ptCen = pArc->GetCenter() ;
|
||||
@@ -121,9 +122,11 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
}
|
||||
}
|
||||
}
|
||||
// elimino casi vicino agli estremi, danno solo problemi
|
||||
if ( dU < 0.1 || dU > 0.9)
|
||||
// non c'è intersezione, assegno valore medio
|
||||
if ( dU < -0.5)
|
||||
dU = 0.5 ;
|
||||
// elimino casi vicino agli estremi, danno solo problemi
|
||||
dU = Clamp( dU, 0.1, 0.9) ;
|
||||
pBiArc.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, dU)) ;
|
||||
}
|
||||
|
||||
@@ -132,15 +135,24 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
return nullptr ;
|
||||
|
||||
// determino la massima distanza tra la curva e il biarco
|
||||
Point3d ptP ;
|
||||
double dSqDist = 0 ;
|
||||
for ( bool bPnt = PL.GetFirstPoint( ptP) ;
|
||||
bPnt ;
|
||||
bPnt = PL.GetNextPoint( ptP)) {
|
||||
DistPointCurve dstPC( ptP, *pBiArc) ;
|
||||
double dSqDistPC ;
|
||||
if ( dstPC.GetSqDist( dSqDistPC) && dSqDistPC > dSqDist)
|
||||
dSqDist = dSqDistPC ;
|
||||
const double STEP = 10 ;
|
||||
Point3d ptCurr ;
|
||||
bool bPnt = PL.GetFirstPoint( ptCurr) ;
|
||||
Point3d ptPrev = ptCurr ;
|
||||
while ( bPnt) {
|
||||
double dLen = Dist( ptCurr, ptPrev) ;
|
||||
int nStep = ( dLen < STEP ? 2 : 1) * int( dLen / STEP) + 1 ;
|
||||
for ( int i = 1 ; i <= nStep ; ++ i) {
|
||||
double dCoeff = double( i) / nStep ;
|
||||
Point3d ptP = Media( ptPrev, ptCurr, dCoeff) ;
|
||||
DistPointCurve dstPC( ptP, *pBiArc) ;
|
||||
double dSqDistPC ;
|
||||
if ( dstPC.GetSqDist( dSqDistPC) && dSqDistPC > dSqDist)
|
||||
dSqDist = dSqDistPC ;
|
||||
}
|
||||
ptPrev = ptCurr ;
|
||||
bPnt = PL.GetNextPoint( ptCurr) ;
|
||||
}
|
||||
dDist = sqrt( dSqDist) ;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EgkBiArcs.h"
|
||||
#include "/EgtDev/Include/EGkBiArcs.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ICurve* GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg,
|
||||
|
||||
+3
-3
@@ -301,11 +301,11 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
|
||||
Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ;
|
||||
b3Tool.Add( ptTL) ;
|
||||
b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ;
|
||||
if ( vtDirL.IsXplus() || vtDirL.IsXminus())
|
||||
if ( vtDirL.IsX())
|
||||
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
|
||||
else if ( vtDirL.IsYplus() || vtDirL.IsYminus())
|
||||
else if ( vtDirL.IsY())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
|
||||
else if ( vtDirL.IsZplus() || vtDirL.IsZminus())
|
||||
else if ( vtDirL.IsZ())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
|
||||
else {
|
||||
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ;
|
||||
|
||||
+17
-13
@@ -23,16 +23,17 @@ using namespace std ;
|
||||
bool
|
||||
CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// recupero BBox del poliedro
|
||||
// Recupero BBox del poliedro
|
||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||
// calcolo il BBox del parallelepipedo
|
||||
BBox3d b3Box( ORIG, ORIG + vtDiag) ;
|
||||
b3Box.Expand( dSafeDist) ;
|
||||
b3Box.ToGlob( frBox) ;
|
||||
// confronto i due Box
|
||||
if ( ! b3Box.Overlaps( b3Poly))
|
||||
// Calcolo il BBox del parallelepipedo
|
||||
BBox3d b3BoxL( ORIG, ORIG + vtDiag) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxL.Expand( dSafeDist) ;
|
||||
BBox3d b3Box = GetToGlob( b3BoxL, frBox) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Poly.Overlaps( b3Box) || ! b3Poly.Overlaps( frBox, b3BoxL))
|
||||
return false ;
|
||||
// recupero i triangoli che interferiscono con il box
|
||||
// Verifico se il parallelepipedo interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Box, vT) ;
|
||||
for ( int nT : vT) {
|
||||
@@ -45,10 +46,13 @@ CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDi
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il box è dentro la superficie tramite calcolo distanza minima.
|
||||
Point3d ptBoxOrig, ptBoxMax ;
|
||||
b3Box.GetMinMax( ptBoxOrig, ptBoxMax) ;
|
||||
DistPointSurfTm DistBoxOrigSurfCalc( ptBoxOrig, Stm) ;
|
||||
// Se il BBox del parallelepipedo non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Poly.Encloses( b3Box) && ! b3Box.Encloses( b3Poly))
|
||||
return false ;
|
||||
// Verifico se il box è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptBoxCen = ORIG + vtDiag / 2 ;
|
||||
ptBoxCen.ToGlob( frBox) ;
|
||||
DistPointSurfTm DistBoxCenSurfCalc( ptBoxCen, Stm) ;
|
||||
// Se il box è interno c'è collisione
|
||||
return DistBoxOrigSurfCalc.IsPointInside() ;
|
||||
return DistBoxCenSurfCalc.IsPointInside() ;
|
||||
}
|
||||
|
||||
+27
-48
@@ -16,6 +16,7 @@
|
||||
#include "CDeBoxTria.h"
|
||||
#include "CDeSpheTria.h"
|
||||
#include "CDeCylTria.h"
|
||||
#include "CDeCapsTria.h"
|
||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||
|
||||
using namespace std ;
|
||||
@@ -99,9 +100,17 @@ CDeSimpleBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, const Triangle3d
|
||||
Triangle3d trTriaL = trTria ;
|
||||
trTriaL.ToLoc( frBox) ;
|
||||
|
||||
// Calcolo il box locale del triangolo
|
||||
BBox3d b3TriaL ;
|
||||
trTriaL.GetLocalBBox( b3TriaL) ;
|
||||
|
||||
// Calcolo il box come tale
|
||||
BBox3d b3Box( ORIG, ORIG + vtDiag) ;
|
||||
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Box.Overlaps( b3TriaL))
|
||||
return false ;
|
||||
|
||||
// Compute box center and extents
|
||||
Point3d ptCen ;
|
||||
Vector3d vtExt ;
|
||||
@@ -173,75 +182,45 @@ CDeBoxTria( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, cons
|
||||
return CDeSimpleBoxTria( Frame3d(), vtDiag, trTriaL) ;
|
||||
|
||||
// Verifica preliminare con box esteso
|
||||
Frame3d frEst( Point3d( -dSafeDist, -dSafeDist, -dSafeDist)) ;
|
||||
if ( ! CDeSimpleBoxTria( frEst, vtDiag + 2 * Vector3d( dSafeDist, dSafeDist, dSafeDist), trTriaL))
|
||||
Frame3d frTmp( Point3d( -dSafeDist, -dSafeDist, -dSafeDist)) ;
|
||||
if ( ! CDeSimpleBoxTria( frTmp, vtDiag + 2 * Vector3d( dSafeDist, dSafeDist, dSafeDist), trTriaL))
|
||||
return false ;
|
||||
|
||||
// Tre box aumentati con distanza di sicurezza in un sola dimensione
|
||||
Frame3d frTmp = frBox ; frTmp.Translate( - dSafeDist * frBox.VersX()) ;
|
||||
frTmp.ChangeOrig( Point3d( -dSafeDist, 0, 0)) ;
|
||||
if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * X_AX, trTriaL))
|
||||
return true ;
|
||||
frTmp = frBox ; frTmp.Translate( - dSafeDist * frBox.VersY()) ;
|
||||
frTmp.ChangeOrig( Point3d( 0, -dSafeDist, 0)) ;
|
||||
if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * Y_AX, trTriaL))
|
||||
return true ;
|
||||
frTmp = frBox ; frTmp.Translate( - dSafeDist * frBox.VersZ()) ;
|
||||
frTmp.ChangeOrig( Point3d( 0, 0, -dSafeDist)) ;
|
||||
if ( CDeSimpleBoxTria( frTmp, vtDiag + 2 * dSafeDist * Z_AX, trTriaL))
|
||||
return true ;
|
||||
|
||||
// Sfere centrate negli otto vertici
|
||||
if ( CDeSimpleSpheTria( Point3d( 0, 0, 0), dSafeDist, trTriaL))
|
||||
// Capsule centrati sui dodici spigoli
|
||||
if ( CDeSimpleCapsTria( Point3d( 0, 0, 0), Point3d( vtDiag.x, 0, 0), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( vtDiag.x, 0, 0), dSafeDist, trTriaL))
|
||||
if ( CDeSimpleCapsTria( Point3d( 0, vtDiag.y, 0), Point3d( vtDiag.x, vtDiag.y, 0), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( vtDiag.x, vtDiag.y, 0), dSafeDist, trTriaL))
|
||||
if ( CDeSimpleCapsTria( Point3d( 0, 0, 0), Point3d( 0, vtDiag.y, 0), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( 0, vtDiag.y, 0), dSafeDist, trTriaL))
|
||||
if ( CDeSimpleCapsTria( Point3d( vtDiag.x, 0, 0), Point3d( vtDiag.x, vtDiag.y, 0), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( 0, 0, vtDiag.z), dSafeDist, trTriaL))
|
||||
if ( CDeSimpleCapsTria( Point3d( 0, 0, vtDiag.z), Point3d( vtDiag.x, 0, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( vtDiag.x, 0, vtDiag.z), dSafeDist, trTriaL))
|
||||
if ( CDeSimpleCapsTria( Point3d( 0, vtDiag.y, vtDiag.z), Point3d( vtDiag.x, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( vtDiag.x, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
|
||||
if ( CDeSimpleCapsTria( Point3d( 0, 0, vtDiag.z), Point3d( 0, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
if ( CDeSimpleSpheTria( Point3d( 0, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
|
||||
if ( CDeSimpleCapsTria( Point3d( vtDiag.x, 0, vtDiag.z), Point3d( vtDiag.x, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
|
||||
// Cilindri centrati sui dodici spigoli
|
||||
frTmp.Set( Point3d( 0, 0, 0), X_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.x, trTriaL))
|
||||
if ( CDeSimpleCapsTria( Point3d( 0, 0, 0), Point3d( 0, 0, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( 0, vtDiag.y, 0), X_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.x, trTriaL))
|
||||
if ( CDeSimpleCapsTria( Point3d( vtDiag.x, 0, 0), Point3d( vtDiag.x, 0, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( 0, 0, 0), Y_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.y, trTriaL))
|
||||
if ( CDeSimpleCapsTria( Point3d( vtDiag.x, vtDiag.y, 0), Point3d( vtDiag.x, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( vtDiag.x, 0, 0), Y_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.y, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( 0, 0, vtDiag.z), X_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.x, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( 0, vtDiag.y, vtDiag.z), X_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.x, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( 0, 0, vtDiag.z), Y_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.y, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( vtDiag.x, 0, vtDiag.z), Y_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.y, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( 0., 0., 0.), Z_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.z, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( vtDiag.x, 0., 0.), Z_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.z, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( vtDiag.x, vtDiag.y, 0.), Z_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.z, trTriaL))
|
||||
return true ;
|
||||
frTmp.Set( Point3d( 0., vtDiag.y, 0.), Z_AX) ;
|
||||
if ( CDeSimpleCylTria( frTmp, dSafeDist, vtDiag.z, trTriaL))
|
||||
if ( CDeSimpleCapsTria( Point3d( 0, vtDiag.y, 0), Point3d( 0, vtDiag.y, vtDiag.z), dSafeDist, trTriaL))
|
||||
return true ;
|
||||
|
||||
return false ;
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2022-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDeCapsTria.cpp Data : 14.05.22 Versione : 2.4e2
|
||||
// Contenuto : Implementazione della verifica di collisione tra
|
||||
// Capsule (cilindro con estremità semisferiche) e Triangle3d.
|
||||
//
|
||||
//
|
||||
// Modifiche :14.05.22 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CDeCapsTria.h"
|
||||
#include "CDeSpheTria.h"
|
||||
#include "ProjPlane.h"
|
||||
#include "IntersLineCaps.h"
|
||||
#include "/EgtDev/Include/EGkPolygon3d.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSphere.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Triangle3d& trTria)
|
||||
{
|
||||
// vedi Ericson, Real-Time Collision Detection, pag. 226 (Nettle method)
|
||||
|
||||
// Dati della capsule come sfera che si muove
|
||||
Point3d ptC = ptP1 ;
|
||||
Point3d ptE = ptP2 ;
|
||||
Vector3d vtDir = ptP2 - ptP1 ;
|
||||
double dLen = vtDir.Len() ;
|
||||
if ( dLen < EPS_SMALL)
|
||||
return CDeSimpleSpheTria( Media( ptP1, ptP2), dR, trTria) ;
|
||||
vtDir /= dLen ;
|
||||
if ( vtDir * trTria.GetN() > 0) {
|
||||
vtDir.Invert() ;
|
||||
ptC = ptP2 ;
|
||||
ptE = ptP1 ;
|
||||
}
|
||||
// Se sfera finale dista dal piano come o meno del raggio, devo verificarla direttamente (il retro è escluso dal calcolo standard)
|
||||
double dDistE = DistPointPlane( ptE, trTria.GetPlane()) ;
|
||||
if ( abs( dDistE) <= dR) {
|
||||
if ( CDeSimpleSpheTria( ptE, dR, trTria))
|
||||
return true ;
|
||||
}
|
||||
// Determinazione primo possibile punto di contatto della sfera con il piano
|
||||
Point3d ptD = ptC - trTria.GetN() * dR ;
|
||||
// Intersezione della linea di movimento di questo punto con il piano del triangolo
|
||||
Point3d ptP ;
|
||||
int nLpRes = IntersLinePlane( ptD, vtDir, 1, trTria.GetPlane(), ptP, false) ;
|
||||
// Se non c'è intersezione passante
|
||||
if ( nLpRes != ILPT_YES) {
|
||||
// se il centro dista dal piano non meno del raggio, allora non c'è sicuramente collisione
|
||||
double dDistM = DistPointPlane( Media( ptP1, ptP2), trTria.GetPlane()) ;
|
||||
if ( abs( dDistM) >= dR)
|
||||
return false ;
|
||||
// interseco l'asse del capsule con capsule di pari raggio con asse i lati del triangolo
|
||||
double dU1 = INFINITO, dU2 = -INFINITO ;
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
double dInt1, dInt2 ;
|
||||
if ( IntersLineCaps( ptC, vtDir, trTria.GetP( i), trTria.GetP( ( i + 1) % 3), dR, dInt1, dInt2)) {
|
||||
dU1 = min( dU1, dInt1) ;
|
||||
dU2 = max( dU2, dInt2) ;
|
||||
if ( ! ( dU1 >= dLen || dU2 <= 0))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
// Determino la posizione dell'intersezione rispetto al triangolo
|
||||
DistPointTriangle dptDist( ptP, trTria) ;
|
||||
// Se l'intersezione sta nel triangolo
|
||||
double dSqDist ;
|
||||
if ( dptDist.GetSqDist( dSqDist) && dSqDist < 4 * SQ_EPS_SMALL) {
|
||||
double dPos = ( ptP - ptD) * vtDir ;
|
||||
return ( dPos > 0 && dPos < dLen) ;
|
||||
}
|
||||
// Altrimenti, recupero il punto del triangolo più vicino all'intersezione
|
||||
Point3d ptQ ;
|
||||
if ( dptDist.GetMinDistPoint( ptQ)) {
|
||||
Point3d ptI1, ptI2 ;
|
||||
int nLsRes = IntersLineSphere( ptQ, -vtDir, ptC, dR, ptI1, ptI2) ;
|
||||
if ( nLsRes != ILST_SEC)
|
||||
return false ;
|
||||
double dPos = ( ptQ - ptI1) * vtDir ;
|
||||
return ( dPos > 0 && dPos < dLen) ;
|
||||
}
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CDeCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, double dSafeDist, const Triangle3d& trTria)
|
||||
{
|
||||
return CDeSimpleCapsTria( ptP1, ptP2, dR + max( 0., dSafeDist), trTria) ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2022-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : EGkCDeCapsTria.h Data : 14.05.22 Versione : 2.4e2
|
||||
// Contenuto : Dichiarazione funzione verifica collisione tra
|
||||
// Capsule (cilindro con estremità semisferiche) e Triangle3d.
|
||||
//
|
||||
// Modifiche : 14.05.22 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkTriangle3d.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Triangle3d& trTria) ;
|
||||
bool CDeCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, double dSafeDist, const Triangle3d& trTria) ;
|
||||
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDeSurfTmSurfTm.h Data : 13.11.20 Versione :
|
||||
// File : CDeSurfTmSurfTm.h Data : 14.06.23 Versione : 2.5f3
|
||||
// Contenuto : Implementazione funzione verifica collisione tra
|
||||
// SurfTm e SurfTm.
|
||||
//
|
||||
@@ -18,8 +18,6 @@
|
||||
#include "/EgtDev/Include/EGkBBox3d.h"
|
||||
#include "/EgtDev/Include/EGkCDeClosedSurfTmClosedSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -33,63 +31,67 @@ using namespace std ;
|
||||
// originale traslato di una costante pari alla distanza di sicurezza lungo la
|
||||
// sua normale.
|
||||
bool
|
||||
CDeClosedSurfTmClosedSurfTm( const SurfTriMesh& SurfA, const SurfTriMesh& SurfB, double dSafeDist)
|
||||
CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist)
|
||||
{
|
||||
// Se le superfici non sono valide o non sono chiuse, non ha senso proseguire.
|
||||
if ( ! ( SurfA.IsValid() && SurfB.IsValid()) || ! ( SurfA.IsClosed() && SurfB.IsClosed()))
|
||||
// Recupero le superfici base
|
||||
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ;
|
||||
const SurfTriMesh* pSrfB = GetBasicSurfTriMesh( &SurfB) ;
|
||||
// Se le superfici non sono valide o non sono chiuse, non ha senso proseguire.
|
||||
if ( pSrfA == nullptr || ! pSrfA->IsValid() || ! pSrfA->IsClosed() ||
|
||||
pSrfB == nullptr || ! pSrfB->IsValid() || ! pSrfB->IsClosed())
|
||||
return false ;
|
||||
// Se i box delle superfici non si intersecano, ho finito.
|
||||
// Se i box delle superfici non si intersecano, ho finito.
|
||||
BBox3d b3BoxA, b3BoxB ;
|
||||
SurfA.GetLocalBBox( b3BoxA) ;
|
||||
SurfB.GetLocalBBox( b3BoxB) ;
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
pSrfA->GetLocalBBox( b3BoxA) ;
|
||||
pSrfB->GetLocalBBox( b3BoxB) ;
|
||||
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxA.Expand( dSafeDist) ;
|
||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||
b3BoxB.Expand( dSafeDist) ;
|
||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||
if ( ! b3BoxA.Overlaps( b3BoxB))
|
||||
return false ;
|
||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||
// Recupero i triangoli di A che interferiscono col box di B
|
||||
INTVECTOR vTriaIndex ;
|
||||
SurfA.GetAllTriaOverlapBox( b3BoxB, vTriaIndex) ;
|
||||
// Ciclo sui triangoli della superficie A che cadono nel box della superficie B.
|
||||
pSrfA->GetAllTriaOverlapBox( b3BoxB, vTriaIndex) ;
|
||||
// Ciclo sui triangoli della superficie A che interferiscono col box della superficie B.
|
||||
for ( int nTA : vTriaIndex) {
|
||||
Triangle3d trTriaA ;
|
||||
if ( ! ( SurfA.GetTriangle( nTA, trTriaA) && trTriaA.Validate()))
|
||||
if ( ! ( pSrfA->GetTriangle( nTA, trTriaA) && trTriaA.Validate()))
|
||||
continue ;
|
||||
BBox3d b3BoxTriaA ;
|
||||
trTriaA.GetLocalBBox( b3BoxTriaA) ;
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxTriaA.Expand( dSafeDist) ;
|
||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||
INTVECTOR vNearTria ;
|
||||
SurfB.GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
||||
// Settare tutti i triangoli come già processati.
|
||||
// Al termine della chiamata i TFlags dei triangoli valgono 0.
|
||||
SurfB.ResetTempInt() ;
|
||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
||||
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
||||
// Settare tutti i triangoli come già processati.
|
||||
// Al termine della chiamata i TempInt dei triangoli valgono 0.
|
||||
pSrfB->ResetTempInts() ;
|
||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
||||
for ( int nTB : vNearTria) {
|
||||
// Recupero il triangolo corrente della superficie B.
|
||||
// Se triangolo non valido salto al successivo.
|
||||
// Recupero il triangolo corrente della superficie B.
|
||||
// Se triangolo non valido salto al successivo.
|
||||
Triangle3d trTriaB ;
|
||||
if ( ! ( SurfB.GetTriangle( nTB, trTriaB) && trTriaB.Validate()))
|
||||
if ( ! ( pSrfB->GetTriangle( nTB, trTriaB) && trTriaB.Validate()))
|
||||
continue ;
|
||||
// Se necessario considero l'offset
|
||||
// Se necessario considero l'offset
|
||||
if ( dSafeDist > EPS_SMALL) {
|
||||
int nAdjTriaId[3] ;
|
||||
SurfB.GetTriangleAdjacencies( nTB, nAdjTriaId) ;
|
||||
// Ciclo sui vertici del triangolo.
|
||||
pSrfB->GetTriangleAdjacencies( nTB, nAdjTriaId) ;
|
||||
// Ciclo sui vertici del triangolo.
|
||||
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
||||
// non è stato processato, processo il vertice e l'edge.
|
||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
||||
// non è stato processato, processo il vertice e l'edge.
|
||||
int nAdjTriaTempFlag ;
|
||||
if ( ! ( SurfB.GetTriangleTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||
continue ;
|
||||
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
||||
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
||||
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
|
||||
return true ;
|
||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||
Vector3d vtEdgeV = trTriaB.GetP( nVB) - trTriaB.GetP( ( nVB + 1) % 3) ;
|
||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
|
||||
double dEdgeLen = vtEdgeV.Len() ;
|
||||
vtEdgeV /= dEdgeLen ;
|
||||
Frame3d frCyl ;
|
||||
@@ -97,22 +99,25 @@ CDeClosedSurfTmClosedSurfTm( const SurfTriMesh& SurfA, const SurfTriMesh& SurfB,
|
||||
if ( CDeSimpleCylTria( frCyl, dSafeDist, dEdgeLen, trTriaA))
|
||||
return true ;
|
||||
}
|
||||
// Traslo il triangolo
|
||||
// Traslo il triangolo
|
||||
trTriaB.Translate( dSafeDist * trTriaB.GetN()) ;
|
||||
}
|
||||
// Processo il triangolo: se i due triangoli collidono ho finito.
|
||||
// Processo il triangolo: se i due triangoli collidono ho finito.
|
||||
if ( CDeTriaTria( trTriaA, trTriaB))
|
||||
return true ;
|
||||
// Segno il triangolo come processato: nTFlag = 1
|
||||
SurfB.SetTempInt( nTB, 1) ;
|
||||
// Segno il triangolo come processato: nTemp = 1
|
||||
pSrfB->SetTempInt( nTB, 1) ;
|
||||
}
|
||||
}
|
||||
// Non ho trovato collisioni fra triangoli delle superfici.
|
||||
// La collisione c'è se una superficie è dentro l'altra.
|
||||
// Non ho trovato collisioni fra triangoli delle superfici.
|
||||
// Se il BBox della prima superficie non è interno a quello della seconda e viceversa, non c'è collisione
|
||||
if ( ! b3BoxA.Encloses( b3BoxB) && ! b3BoxB.Encloses( b3BoxA))
|
||||
return false ;
|
||||
// La collisione c'è se una superficie è dentro l'altra.
|
||||
Point3d ptPointA, ptPointB ;
|
||||
SurfA.GetFirstVertex( ptPointA) ;
|
||||
SurfB.GetFirstVertex( ptPointB) ;
|
||||
DistPointSurfTm DistPoinASurfB( ptPointA, SurfB) ;
|
||||
DistPointSurfTm DistPoinBSurfA( ptPointB, SurfA) ;
|
||||
return ( DistPoinASurfB.IsPointInside() || DistPoinBSurfA.IsPointInside()) ;
|
||||
}
|
||||
pSrfA->GetFirstVertex( ptPointA) ;
|
||||
pSrfB->GetFirstVertex( ptPointB) ;
|
||||
DistPointSurfTm DistPoinASrfB( ptPointA, *pSrfB) ;
|
||||
DistPointSurfTm DistPoinBSrfA( ptPointB, *pSrfA) ;
|
||||
return ( DistPoinASrfB.IsPointInside() || DistPoinBSrfA.IsPointInside()) ;
|
||||
}
|
||||
|
||||
@@ -20,31 +20,32 @@
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Il sisitema di riferimento deve avere l'asse di simmetria del cono come asse Z e origine nel centro della base.
|
||||
// Il sistema di riferimento deve avere l'asse di simmetria del cono come asse Z e origine nel centro della base.
|
||||
// La distanza di sicurezza ha effetto solo se maggiore di epsilon, altrimenti è ignorata ed è ininfluente.
|
||||
// Il sistema di riferimento del cono deve essere immerso in quello della superficie.
|
||||
bool
|
||||
CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
|
||||
double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// Se il tronco di cono non è ben definito non ha senso proseguire.
|
||||
// Se il tronco di cono non è ben definito non ha senso proseguire
|
||||
if ( max( dBaseRad, dTopRad) < EPS_SMALL || dHeight < EPS_SMALL)
|
||||
return false ;
|
||||
// Recupero BBox della trimesh
|
||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||
// Calcolo il BBox del tronco di cono
|
||||
double dMaxRad = max( dBaseRad, dTopRad) ;
|
||||
BBox3d b3Cone( - dMaxRad, - dMaxRad, 0, dMaxRad, dMaxRad, dHeight) ;
|
||||
b3Cone.Expand( dSafeDist) ;
|
||||
// Porto BBox del cono nel sistema della superficie.
|
||||
b3Cone.ToGlob( frCone) ;
|
||||
// Se i BBox non interferiscono, ho finito.
|
||||
if ( ! b3Cone.Overlaps( b3Surf))
|
||||
BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0),
|
||||
Point3d( dMaxRad, dMaxRad, dHeight)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3ConeL.Expand( dSafeDist) ;
|
||||
BBox3d b3Cone = GetToGlob( b3ConeL, frCone) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Surf.Overlaps( b3Cone) || ! b3Surf.Overlaps( frCone, b3ConeL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del cono
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Cone, vT) ;
|
||||
// Ciclo sui triangoli che interferiscono col box del cono
|
||||
// Verifico se il tronco di cono interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
@@ -55,10 +56,13 @@ CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopR
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Se il BBox del tronco di cono non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Surf.Encloses( b3Cone) && ! b3Cone.Encloses( b3Surf))
|
||||
return false ;
|
||||
// Verifico se il tronco di cono è dentro la superficie tramite calcolo distanza minima.
|
||||
Point3d ptConeOrig ;
|
||||
ptConeOrig.ToGlob( frCone) ;
|
||||
DistPointSurfTm DistConeOrigSurfCalc( ptConeOrig, Stm) ;
|
||||
Point3d ptConeCen( 0, 0, dHeight / 2) ;
|
||||
ptConeCen.ToGlob( frCone) ;
|
||||
DistPointSurfTm DistConeCenSurfCalc( ptConeCen, Stm) ;
|
||||
// Se il tronco di cono è interno c'è collisione
|
||||
return DistConeOrigSurfCalc.IsPointInside() ;
|
||||
return DistConeCenSurfCalc.IsPointInside() ;
|
||||
}
|
||||
@@ -23,42 +23,42 @@ using namespace std ;
|
||||
// Il toro è posto nel piano XY del suo riferimento, centrato sull'origine.
|
||||
// La funzione restituisce true in caso di collisione.
|
||||
bool
|
||||
CDeConvexTorusClosedSurfTm( const Frame3d& frTorusFrame, double dRad1, double dRad2,
|
||||
CDeConvexTorusClosedSurfTm( const Frame3d& frTorus, double dRad1, double dRad2,
|
||||
double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// I raggi devono essere non nulli e la superficie ben definita.
|
||||
if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! Stm.IsValid())
|
||||
return false ;
|
||||
// Box del toro (sempre completo)
|
||||
BBox3d b3ConvTorusBox ;
|
||||
b3ConvTorusBox.Set( Point3d( - dRad1 - dRad2, - dRad1 - dRad2, - dRad2),
|
||||
Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
|
||||
// Aggiungo eventuale distanza di sicurezza
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3ConvTorusBox.Expand( dSafeDist) ;
|
||||
// Porto il box del toro nel riferimento della superficie (inteso some globale)
|
||||
b3ConvTorusBox.ToGlob( frTorusFrame) ;
|
||||
// Box della superficie
|
||||
BBox3d b3SurfBox = Stm.GetAllTriaBox() ;
|
||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||
// Box del toro (sempre completo)
|
||||
BBox3d b3TorusL( Point3d( -dRad1 - dRad2, -dRad1 - dRad2, -dRad2),
|
||||
Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3TorusL.Expand( dSafeDist) ;
|
||||
BBox3d b3Torus = GetToGlob( b3TorusL, frTorus) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3ConvTorusBox.Overlaps( b3SurfBox))
|
||||
if ( ! b3Surf.Overlaps( b3Torus) || ! b3Surf.Overlaps( frTorus, b3TorusL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del toro
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3ConvTorusBox, vT) ;
|
||||
// Ciclo sui triangoli recuperati
|
||||
Stm.GetAllTriaOverlapBox( b3Torus, vT) ;
|
||||
// Verifico se il toro interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
if ( CDeConvexTorusTria( frTorusFrame, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
|
||||
if ( CDeConvexTorusTria( frTorus, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il toro è dentro la superficie tramite calcolo distanza minima.
|
||||
Point3d ptTorusOrig = frTorusFrame.Orig() ;
|
||||
// Se il BBox del toro non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Surf.Encloses( b3Torus) && ! b3Torus.Encloses( b3Surf))
|
||||
return false ;
|
||||
// Verifico se il toro è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptTorusOrig = frTorus.Orig() ;
|
||||
DistPointSurfTm DistConeOrigSurfCalc( ptTorusOrig, Stm) ;
|
||||
// Se il toro è interno c'è collisione
|
||||
return ( DistConeOrigSurfCalc.IsPointInside()) ;
|
||||
|
||||
+22
-17
@@ -23,38 +23,43 @@ using namespace std ;
|
||||
bool
|
||||
CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// recupero BBox del poliedro
|
||||
// Recupero BBox del poliedro
|
||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||
// sistemazioni cilindro
|
||||
Frame3d frC = frCyl ;
|
||||
// Sistemazioni cilindro
|
||||
Frame3d frMyCyl = frCyl ;
|
||||
if ( dH < 0) {
|
||||
frC.Translate( dH * frC.VersZ()) ;
|
||||
frMyCyl.Translate( dH * frMyCyl.VersZ()) ;
|
||||
dH = - dH ;
|
||||
}
|
||||
// calcolo il BBox del cilindro
|
||||
BBox3d b3Cyl( -dR, -dR, 0, dR, dR, dH) ;
|
||||
b3Cyl.Expand( dSafeDist) ;
|
||||
b3Cyl.ToGlob( frC) ;
|
||||
// confronto i due Box
|
||||
if ( ! b3Cyl.Overlaps( b3Poly))
|
||||
// Calcolo il BBox del cilindro
|
||||
BBox3d b3CylL( Point3d( -dR, -dR, 0),
|
||||
Point3d( dR, dR, dH)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3CylL.Expand( dSafeDist) ;
|
||||
BBox3d b3Cyl = GetToGlob( b3CylL, frMyCyl) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Poly.Overlaps( b3Cyl) || ! b3Poly.Overlaps( frMyCyl, b3CylL))
|
||||
return false ;
|
||||
// recupero i triangoli che interferiscono con il box del Cilindro
|
||||
// Verifico se il cilindro interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Cyl, vT) ;
|
||||
for ( int nT : vT) {
|
||||
Triangle3d Tria ;
|
||||
if ( Stm.GetTriangle( nT, Tria)) {
|
||||
if ( CDeCylTria( frC, dR, dH, dSafeDist, Tria))
|
||||
if ( CDeCylTria( frMyCyl, dR, dH, dSafeDist, Tria))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima.
|
||||
Point3d ptCylOrig( 0., 0., - dSafeDist) ;
|
||||
ptCylOrig.ToGlob( frC) ;
|
||||
DistPointSurfTm DistCylOrigSurfCalc( ptCylOrig, Stm) ;
|
||||
// Se il BBox del cilindro non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Poly.Encloses( b3Cyl) && ! b3Cyl.Encloses( b3Poly))
|
||||
return false ;
|
||||
// Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptCylCen( 0, 0, dH / 2) ;
|
||||
ptCylCen.ToGlob( frMyCyl) ;
|
||||
DistPointSurfTm DistCylCenSurfCalc( ptCylCen, Stm) ;
|
||||
// Se il cilindro è interno c'è collisione
|
||||
return ( DistCylOrigSurfCalc.IsPointInside()) ;
|
||||
return ( DistCylCenSurfCalc.IsPointInside()) ;
|
||||
}
|
||||
|
||||
@@ -37,20 +37,18 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
|
||||
// Calcolo il BBox del tronco di piramide
|
||||
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
|
||||
double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ;
|
||||
BBox3d b3Pyr( -dMaxLenX / 2, -dMaxLenY / 2, 0., dMaxLenX / 2, dMaxLenY / 2, dHeight) ;
|
||||
// Se la distanza di sicurezza è maggiore di epsilon aumento le dimensioni del tronco di piramide.
|
||||
if ( dSafeDist > EPS_SMALL) {
|
||||
b3Pyr.Expand( dSafeDist) ;
|
||||
}
|
||||
// Porto BBox del tronco di piramide nel sistema della superficie.
|
||||
b3Pyr.ToGlob( frPrismoid) ;
|
||||
BBox3d b3PyrL( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
|
||||
Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3PyrL.Expand( dSafeDist) ;
|
||||
BBox3d b3Pyr = GetToGlob( b3PyrL, frPrismoid) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Pyr.Overlaps( b3Surf))
|
||||
if ( ! b3Surf.Overlaps( b3Pyr) || ! b3Surf.Overlaps( frPrismoid, b3PyrL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del tronco di piramide.
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Pyr, vT) ;
|
||||
// Ciclo sui triangoli che interferiscono col box del tronco di piramide.
|
||||
// Verifico se il tronco di piramide interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
@@ -62,9 +60,13 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima.
|
||||
Point3d ptPyrOrig = frPrismoid.Orig() ;
|
||||
DistPointSurfTm DistBoxOrigSurfCalc( ptPyrOrig, Stm) ;
|
||||
// C'è collisione se il tronco di piramide è interno.
|
||||
return ( DistBoxOrigSurfCalc.IsPointInside()) ;
|
||||
// Se il BBox del tronco di piramide non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Surf.Encloses( b3Pyr) && ! b3Pyr.Encloses( b3Surf))
|
||||
return false ;
|
||||
// Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
Point3d ptPyrCen( 0, 0, dHeight / 2) ;
|
||||
ptPyrCen.ToGlob( frPrismoid) ;
|
||||
DistPointSurfTm DistPyrCenSurfCalc( ptPyrCen, Stm) ;
|
||||
// C'è collisione se il tronco di piramide è interno
|
||||
return ( DistPyrCenSurfCalc.IsPointInside()) ;
|
||||
}
|
||||
|
||||
+33
-53
@@ -14,6 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CDeRectPrismoidTria.h"
|
||||
#include "CDeCapsTria.h"
|
||||
#include "CDeBoxTria.h"
|
||||
#include "CDeCylTria.h"
|
||||
#include "CDeSpheTria.h"
|
||||
@@ -141,9 +142,13 @@ CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLen
|
||||
dHeight < EPS_SMALL || ! trTria.IsValid())
|
||||
return false ;
|
||||
|
||||
// Porto il triangolo nel riferimento del prismoide
|
||||
Triangle3d trTriaL = trTria ;
|
||||
trTriaL.ToLoc( frPrismoid) ;
|
||||
|
||||
// Se distanza di sicurezza nulla
|
||||
if ( dSafeDist < EPS_SMALL)
|
||||
return CDeSimpleRectPrismoidTria( frPrismoid, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight, trTria) ;
|
||||
return CDeSimpleRectPrismoidTria( Frame3d(), dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight, trTriaL) ;
|
||||
|
||||
// Verifiche con offset esteso
|
||||
double dHDiffX = ( dLenghtBaseX - dLenghtTopX) / 2 ;
|
||||
@@ -156,37 +161,37 @@ CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLen
|
||||
double dSecAy = sqrt( 1 + dTgAy * dTgAy) ;
|
||||
double dOffsBaseY = dSafeDist * ( dSecAy + dTgAy) ;
|
||||
double dOffsTopY = dSafeDist * ( dSecAy - dTgAy) ;
|
||||
Frame3d frFrame = frPrismoid ; frFrame.Translate( - dSafeDist * frFrame.VersZ()) ;
|
||||
if ( ! CDeSimpleRectPrismoidTria( frFrame, dLenghtBaseX + 2 * dOffsBaseX, dLenghtBaseY + 2 * dOffsBaseY,
|
||||
dLenghtTopX + 2 * dOffsTopX, dLenghtTopY + 2 * dOffsTopY, dHeight + 2 * dSafeDist, trTria))
|
||||
Frame3d frTmp( Point3d( 0, 0, -dSafeDist)) ;
|
||||
if ( ! CDeSimpleRectPrismoidTria( frTmp, dLenghtBaseX + 2 * dOffsBaseX, dLenghtBaseY + 2 * dOffsBaseY,
|
||||
dLenghtTopX + 2 * dOffsTopX, dLenghtTopY + 2 * dOffsTopY, dHeight + 2 * dSafeDist, trTriaL))
|
||||
return false ;
|
||||
|
||||
// Offset fine
|
||||
// Box sotto
|
||||
frFrame = frPrismoid ; frFrame.Translate( - dSafeDist * frFrame.VersZ()) ;
|
||||
if ( CDeSimpleBoxTria( frFrame, Vector3d( dLenghtBaseX, dLenghtBaseY, dSafeDist), trTria))
|
||||
frTmp.ChangeOrig( Point3d( 0, 0, -dSafeDist)) ;
|
||||
if ( CDeSimpleBoxTria( frTmp, Vector3d( dLenghtBaseX, dLenghtBaseY, dSafeDist), trTriaL))
|
||||
return true ;
|
||||
// Box sopra
|
||||
frFrame = frPrismoid ; frFrame.Translate( dHeight * frFrame.VersZ()) ;
|
||||
if ( CDeSimpleBoxTria( frFrame, Vector3d( dLenghtTopX, dLenghtTopY, dSafeDist), trTria))
|
||||
frTmp.ChangeOrig( Point3d( 0, 0, dHeight)) ;
|
||||
if ( CDeSimpleBoxTria( frTmp, Vector3d( dLenghtTopX, dLenghtTopY, dSafeDist), trTriaL))
|
||||
return true ;
|
||||
// Prismoide allungato in X
|
||||
double dHypoX = sqrt( dHDiffX * dHDiffX + dHeight * dHeight) ;
|
||||
double dOffsX = dSafeDist * dHeight / dHypoX ;
|
||||
double dMoveXZ = dSafeDist * dHDiffX / dHypoX ;
|
||||
frFrame = frPrismoid ; frFrame.Translate( dMoveXZ * frFrame.VersZ()) ;
|
||||
if ( CDeSimpleRectPrismoidTria( frFrame, dLenghtBaseX + 2 * dOffsX, dLenghtBaseY,
|
||||
dLenghtTopX + 2 * dOffsX, dLenghtTopY, dHeight, trTria))
|
||||
frTmp.ChangeOrig( Point3d( 0, 0, dMoveXZ)) ;
|
||||
if ( CDeSimpleRectPrismoidTria( frTmp, dLenghtBaseX + 2 * dOffsX, dLenghtBaseY,
|
||||
dLenghtTopX + 2 * dOffsX, dLenghtTopY, dHeight, trTriaL))
|
||||
return true ;
|
||||
// Prismoide allungato in Y
|
||||
double dHypoY = sqrt( dHDiffY * dHDiffY + dHeight * dHeight) ;
|
||||
double dOffsY = dSafeDist * dHeight / dHypoY ;
|
||||
double dMoveYZ = dSafeDist * dHDiffY / dHypoY ;
|
||||
frFrame = frPrismoid ; frFrame.Translate( dMoveYZ * frFrame.VersZ()) ;
|
||||
if ( CDeSimpleRectPrismoidTria( frFrame, dLenghtBaseX, dLenghtBaseY + 2 * dOffsY,
|
||||
dLenghtTopX, dLenghtTopY + 2 * dOffsY, dHeight, trTria))
|
||||
frTmp.ChangeOrig( Point3d( 0, 0, dMoveYZ)) ;
|
||||
if ( CDeSimpleRectPrismoidTria( frTmp, dLenghtBaseX, dLenghtBaseY + 2 * dOffsY,
|
||||
dLenghtTopX, dLenghtTopY + 2 * dOffsY, dHeight, trTriaL))
|
||||
return true ;
|
||||
// Sfere centrate nei vertici
|
||||
// Vertici
|
||||
double dHalfBaseX = dLenghtBaseX / 2 ;
|
||||
double dHalfBaseY = dLenghtBaseY / 2 ;
|
||||
double dHalfTopX = dLenghtTopX / 2 ;
|
||||
@@ -199,55 +204,30 @@ CDeRectPrismoidTria( const Frame3d& frPrismoid, double dLenghtBaseX, double dLen
|
||||
Point3d( dHalfTopX, -dHalfTopY, dHeight),
|
||||
Point3d( dHalfTopX, dHalfTopY, dHeight),
|
||||
Point3d( -dHalfTopX, dHalfTopY, dHeight)} ;
|
||||
for ( auto& ptV : vVert) {
|
||||
ptV.ToGlob( frPrismoid) ;
|
||||
if ( CDeSimpleSpheTria( ptV, dSafeDist, trTria))
|
||||
return true ;
|
||||
}
|
||||
// Cilindri con i segmenti come asse
|
||||
frFrame.Set( vVert[0], frPrismoid.VersX()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtBaseX, trTria))
|
||||
// Capsule centrati sui dodici spigoli
|
||||
if ( CDeSimpleCapsTria( vVert[0], vVert[1], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[1], frPrismoid.VersY()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtBaseY, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[1], vVert[2], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[2], -frPrismoid.VersX()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtBaseX, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[2], vVert[3], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[3], -frPrismoid.VersY()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtBaseY, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[3], vVert[0], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[4], frPrismoid.VersX()) ;
|
||||
if (CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopX, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[4], vVert[5], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[5], frPrismoid.VersY()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopY, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[5], vVert[6], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[6], -frPrismoid.VersX()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopX, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[6], vVert[7], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
frFrame.Set( vVert[7], -frPrismoid.VersY()) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenghtTopY, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[7], vVert[4], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
Vector3d vtSeg04 = vVert[4] - vVert[0] ;
|
||||
double dLenSeg04 = vtSeg04.Len() ;
|
||||
frFrame.Set( vVert[0], vtSeg04) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg04, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[0], vVert[4], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
Vector3d vtSeg15 = vVert[5] - vVert[1] ;
|
||||
double dLenSeg15 = vtSeg15.Len() ;
|
||||
frFrame.Set( vVert[1], vtSeg15) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg15, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[1], vVert[5], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
Vector3d vtSeg26 = vVert[6] - vVert[2] ;
|
||||
double dLenSeg26 = vtSeg26.Len() ;
|
||||
frFrame.Set( vVert[2], vtSeg26) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg26, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[2], vVert[6], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
Vector3d vtSeg37 = vVert[7] - vVert[3] ;
|
||||
double dLenSeg37 = vtSeg37.Len();
|
||||
frFrame.Set( vVert[3], vtSeg37) ;
|
||||
if ( CDeSimpleCylTria( frFrame, dSafeDist, dLenSeg37, trTria))
|
||||
if ( CDeSimpleCapsTria( vVert[3], vVert[7], dSafeDist, trTriaL))
|
||||
return true ;
|
||||
|
||||
return false ;
|
||||
|
||||
+11
-7
@@ -23,15 +23,16 @@ using namespace std ;
|
||||
bool
|
||||
CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const ISurfTriMesh& Stm)
|
||||
{
|
||||
// recupero BBox del poliedro
|
||||
// Recupero BBox del poliedro
|
||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||
// calcolo il BBox della sfera
|
||||
// Calcolo il BBox della sfera
|
||||
BBox3d b3Sphe( ptCen, dR) ;
|
||||
b3Sphe.Expand( dSafeDist) ;
|
||||
// confronto i due Box
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Sphe.Expand( dSafeDist) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Sphe.Overlaps( b3Poly))
|
||||
return false ;
|
||||
// recupero i triangoli che interferiscono con il box della Sfera
|
||||
// Verifico se la sfera interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Sphe, vT) ;
|
||||
for ( int nT : vT) {
|
||||
@@ -44,8 +45,11 @@ CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const IS
|
||||
// Se superficie aperta, non c'è collisione
|
||||
if ( ! Stm.IsClosed())
|
||||
return false ;
|
||||
// Verifico se la sfera è dentro la superficie tramite calcolo distanza minima.
|
||||
// Se il BBox della sfera non è interno a quello del poliedro e viceversa, non c'è collisione
|
||||
if ( ! b3Sphe.Encloses( b3Poly) && ! b3Poly.Encloses( b3Sphe))
|
||||
return false ;
|
||||
// Verifico se la sfera è dentro la superficie tramite calcolo distanza minima del suo centro
|
||||
DistPointSurfTm DistCenSurfCalc( ptCen, Stm) ;
|
||||
// C'è collisione se la sfera è interna.
|
||||
// C'è collisione se la sfera è interna.
|
||||
return ( DistCenSurfCalc.IsPointInside()) ;
|
||||
}
|
||||
|
||||
+5
-5
@@ -109,7 +109,7 @@ CDeTriaTria( const Triangle3d& trTriaA, const Triangle3d& trTriaB)
|
||||
DistLineLine LineLineDistCalc( ptStA, PtEnA, ptStB, PtEnB) ;
|
||||
double dSqSegSegDist ;
|
||||
LineLineDistCalc.GetSqDist( dSqSegSegDist) ;
|
||||
if ( dSqSegSegDist < EPS_SMALL * EPS_SMALL)
|
||||
if ( dSqSegSegDist < SQ_EPS_SMALL)
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
@@ -136,14 +136,14 @@ CDeTriaTria( const Triangle3d& trTriaA, const Triangle3d& trTriaB)
|
||||
vtSegFirstA /= dSegLenFirstA ;
|
||||
DistLineLine LineLineDistCalcFirstA( ptLineP, vtLineV, 100., trTriaA.GetP( nFirstMaxPosA), vtSegFirstA, dSegLenFirstA, false) ;
|
||||
double dIntParStA, dOtherParFirstA ;
|
||||
LineLineDistCalcFirstA.GetParamsAtMinDistPoints( dIntParStA, dOtherParFirstA) ;
|
||||
LineLineDistCalcFirstA.GetPositionsAtMinDistPoints( dIntParStA, dOtherParFirstA) ;
|
||||
// Limito la retta col secondo segmento trovato di A
|
||||
Vector3d vtSegSecondA = trTriaA.GetP( ( nSecondMaxPosA + 1) % 3) - trTriaA.GetP( nSecondMaxPosA) ;
|
||||
double dSegLenSecondA = vtSegSecondA.Len() ;
|
||||
vtSegSecondA /= dSegLenSecondA ;
|
||||
DistLineLine LineLineDistCalcSecondA( ptLineP, vtLineV, 100., trTriaA.GetP( nSecondMaxPosA), vtSegSecondA, dSegLenSecondA, false) ;
|
||||
double dIntParEnA, dOtherParSecondA ;
|
||||
LineLineDistCalcSecondA.GetParamsAtMinDistPoints( dIntParEnA, dOtherParSecondA) ;
|
||||
LineLineDistCalcSecondA.GetPositionsAtMinDistPoints( dIntParEnA, dOtherParSecondA) ;
|
||||
// Ordino i parametri lungo la retta di intersezione fra i piani
|
||||
if ( dIntParStA > dIntParEnA) {
|
||||
swap( dIntParStA, dIntParEnA) ;
|
||||
@@ -163,14 +163,14 @@ CDeTriaTria( const Triangle3d& trTriaA, const Triangle3d& trTriaB)
|
||||
vtSegFirstB /= dSegLenFirstB ;
|
||||
DistLineLine LineLineDistCalcFirstB( ptLineP, vtLineV, 100., trTriaB.GetP( nFirstMaxPosB), vtSegFirstB, dSegLenFirstB, false) ;
|
||||
double dIntParStB, dOtherParFirstB ;
|
||||
LineLineDistCalcFirstB.GetParamsAtMinDistPoints( dIntParStB, dOtherParFirstB) ;
|
||||
LineLineDistCalcFirstB.GetPositionsAtMinDistPoints( dIntParStB, dOtherParFirstB) ;
|
||||
// Limito la retta col secondo segmento trovato di B
|
||||
Vector3d vtSegSecondB = trTriaB.GetP( ( nSecondMaxPosB + 1) % 3) - trTriaB.GetP( nSecondMaxPosB) ;
|
||||
double dSegLenSecondB = vtSegSecondB.Len() ;
|
||||
vtSegSecondB /= dSegLenSecondB ;
|
||||
DistLineLine LineLineDistCalcSecondB( ptLineP, vtLineV, 100., trTriaB.GetP( nSecondMaxPosA), vtSegSecondB, dSegLenSecondB, false) ;
|
||||
double dIntParEnB, dOtherParSecondB ;
|
||||
LineLineDistCalcSecondB.GetParamsAtMinDistPoints( dIntParEnB, dOtherParSecondB) ;
|
||||
LineLineDistCalcSecondB.GetPositionsAtMinDistPoints( dIntParEnB, dOtherParSecondB) ;
|
||||
// Ordino i parametri lungo la retta di intersezione fra i piani
|
||||
if ( dIntParStB > dIntParEnB) {
|
||||
swap( dIntParStB, dIntParEnB) ;
|
||||
|
||||
+3
-3
@@ -13,9 +13,9 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "/EgtDev/Include/EgkChainCurves.h"
|
||||
#include "/EgtDev/Include/EgkGeomDB.h"
|
||||
#include "/EgtDev/Include/EgkCurve.h"
|
||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||
#include "/EgtDev/Include/EGkGeomDB.h"
|
||||
#include "/EgtDev/Include/EGkCurve.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2022-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : Circle2P.cpp Data : 18.08.22 Versione : 2.4h2
|
||||
// Contenuto : Implementazione funzioni per calcolo circonferenze per 2 punti
|
||||
// diametrali.
|
||||
//
|
||||
//
|
||||
// Modifiche : 18.08.22 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveArc.h"
|
||||
#include "/EgtDev/Include/EGkCircle2P.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurveArc*
|
||||
GetCircle2P( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtN)
|
||||
{
|
||||
// Verifico che i due punti siano distinti
|
||||
if ( AreSamePointEpsilon( ptP1, ptP2, EPS_SMALL))
|
||||
return nullptr ;
|
||||
// verifico che la normale non sia allineata con i punti
|
||||
Vector3d vtO = OrthoCompo( vtN, ptP2 - ptP1) ;
|
||||
if ( ! vtO.Normalize())
|
||||
return nullptr ;
|
||||
|
||||
// Creo l'oggetto arco
|
||||
PtrOwner<CurveArc> pCrvArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pCrvArc))
|
||||
return nullptr ;
|
||||
|
||||
// Eseguo calcoli
|
||||
if ( ! pCrvArc->SetCPAN( Media( ptP1, ptP2), ptP1, ANG_FULL, 0, vtO))
|
||||
return nullptr ;
|
||||
|
||||
return Release( pCrvArc) ;
|
||||
}
|
||||
@@ -18,8 +18,8 @@
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkCircleCenTgCurve.h"
|
||||
#include "/EgtDev/Include/EgkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkCircleCenTgCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
@@ -239,7 +239,7 @@ GetCircleCenTgCompo( const Point3d& ptCen, const Vector3d& vtN, const CurveCompo
|
||||
double dSqDist = SqDist( ptNear, ptTg) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvArc.Set( Release( pCrvAtmp)) ;
|
||||
pCrvArc.Set( pCrvAtmp) ;
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "/EgtDev/Include/EGkColor.h"
|
||||
#include "/EgtDev/Include/EGkAngle.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include "/EgtDev/Include/EGtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
+136
-81
@@ -25,6 +25,8 @@
|
||||
#include "/EgtDev/Include/EGkAngle.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkUiUnits.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <new>
|
||||
|
||||
@@ -59,8 +61,10 @@ class ArcApproxer
|
||||
//----------------------------------------------------------------------------
|
||||
CurveArc::CurveArc( void)
|
||||
: m_nStatus( TO_VERIFY), m_PtCen(), m_VtN(), m_VtS(), m_dRad(),
|
||||
m_dAngCenDeg(), m_dDeltaN(), m_VtExtr(), m_dThick(), m_nTempProp()
|
||||
m_dAngCenDeg(), m_dDeltaN(), m_VtExtr(), m_dThick()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -564,7 +568,7 @@ CurveArc::Clone( void) const
|
||||
bool
|
||||
CurveArc::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const CurveArc* pCA = dynamic_cast<const CurveArc*>( pGObjSrc) ;
|
||||
const CurveArc* pCA = GetBasicCurveArc( pGObjSrc) ;
|
||||
if ( pCA == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pCA) ;
|
||||
@@ -578,7 +582,8 @@ CurveArc::CopyFrom( const CurveArc& caSrc)
|
||||
return true ;
|
||||
m_VtExtr = caSrc.m_VtExtr ;
|
||||
m_dThick = caSrc.m_dThick ;
|
||||
m_nTempProp = caSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = caSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = caSrc.m_nTempProp[1] ;
|
||||
return Set( caSrc.m_PtCen, caSrc.m_VtN, caSrc.m_dRad,
|
||||
caSrc.m_VtS, caSrc.m_dAngCenDeg, caSrc.m_dDeltaN) ;
|
||||
}
|
||||
@@ -696,29 +701,8 @@ CurveArc::Load( NgeReader& ngeIn)
|
||||
bool
|
||||
CurveArc::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// assegno il box in locale
|
||||
b3Loc.Reset() ;
|
||||
double dLinTol = LIN_TOL_APPROX ;
|
||||
double dAngTolDeg = ANG_TOL_APPROX_DEG ;
|
||||
if ( ( nFlag & BBF_EXACT) != 0)
|
||||
dLinTol = LIN_TOL_MIN ;
|
||||
ArcApproxer aAppr( dLinTol, dAngTolDeg, false, *this) ;
|
||||
double dU ;
|
||||
Point3d ptPos ;
|
||||
while ( aAppr.GetPoint( dU, ptPos))
|
||||
b3Loc.Add( ptPos) ;
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
|
||||
Point3d ptMinExtr = b3Loc.GetMin() + m_VtExtr * m_dThick ;
|
||||
Point3d ptMaxExtr = b3Loc.GetMax() + m_VtExtr * m_dThick ;
|
||||
b3Loc.Add( ptMinExtr) ;
|
||||
b3Loc.Add( ptMaxExtr) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
// richiamo della funzione generale
|
||||
return GetBBox( GLOB_FRM, b3Loc, nFlag) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -733,17 +717,88 @@ CurveArc::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
return false ;
|
||||
// assegno il box nel riferimento
|
||||
b3Ref.Reset() ;
|
||||
double dLinTol = LIN_TOL_APPROX ;
|
||||
double dAngTolDeg = ANG_TOL_APPROX_DEG ;
|
||||
if ( ( nFlag & BBF_EXACT) != 0)
|
||||
dLinTol = LIN_TOL_MIN ;
|
||||
ArcApproxer aAppr( dLinTol, dAngTolDeg, false, *this) ;
|
||||
double dU ;
|
||||
Point3d ptPos ;
|
||||
while ( aAppr.GetPoint( dU, ptPos)) {
|
||||
ptPos.ToGlob( frRef) ;
|
||||
b3Ref.Add( ptPos) ;
|
||||
|
||||
// ricavo il riferimento intrinseco dell'arco
|
||||
Frame3d frArc;
|
||||
frArc.Set( m_PtCen, ( m_dAngCenDeg > 0 ? m_VtN : -m_VtN), m_VtS) ;
|
||||
|
||||
// pendenza intrinseca
|
||||
double dPitch = m_dDeltaN * ( m_dAngCenDeg > 0 ? 1 : -1) / abs( m_dAngCenDeg * DEGTORAD) ;
|
||||
|
||||
// cordinate nel frRef dei versori del sistema di riferimento dell'arco
|
||||
Vector3d vtXRef = frArc.VersX() ;
|
||||
vtXRef.ToGlob( frRef) ;
|
||||
Vector3d vtYRef = frArc.VersY() ;
|
||||
vtYRef.ToGlob( frRef) ;
|
||||
Vector3d vtZRef = frArc.VersZ() ;
|
||||
vtZRef.ToGlob( frRef) ;
|
||||
|
||||
// il punto iniziale e finale sono punti candidati per estremanti
|
||||
Point3d ptS, ptE ;
|
||||
GetStartPoint( ptS) ;
|
||||
ptS.ToGlob( frRef) ;
|
||||
b3Ref.Add( ptS) ;
|
||||
GetEndPoint( ptE) ;
|
||||
ptE.ToGlob( frRef) ;
|
||||
b3Ref.Add( ptE) ;
|
||||
|
||||
// vettore degli angoli dei punti candidati estremi
|
||||
DBLVECTOR vdTheta ;
|
||||
|
||||
// arco piatto
|
||||
if ( abs( dPitch) < EPS_SMALL) {
|
||||
double dAngXDeg = atan2( vtYRef.x, vtXRef.x) * RADTODEG ;
|
||||
bool bAngXSmall = (abs( dAngXDeg) <= EPS_ANG_ZERO) ;
|
||||
if ( ! bAngXSmall) {
|
||||
vdTheta.push_back( dAngXDeg) ;
|
||||
vdTheta.push_back( dAngXDeg + ANG_STRAIGHT) ;
|
||||
}
|
||||
double dAngYDeg = atan2( vtYRef.y, vtXRef.y) * RADTODEG ;
|
||||
bool bAngYSmall = (abs( dAngYDeg) <= EPS_ANG_ZERO) ;
|
||||
if ( ! bAngYSmall) {
|
||||
vdTheta.push_back( dAngYDeg) ;
|
||||
vdTheta.push_back( dAngYDeg + ANG_STRAIGHT) ;
|
||||
}
|
||||
double dAngZDeg = atan2( vtYRef.z, vtXRef.z) * RADTODEG ;
|
||||
bool bAngZSmall = (abs( dAngZDeg) <= EPS_ANG_ZERO) ;
|
||||
if ( ! bAngZSmall) {
|
||||
vdTheta.push_back( dAngZDeg) ;
|
||||
vdTheta.push_back( dAngZDeg + ANG_STRAIGHT) ;
|
||||
}
|
||||
if ( bAngXSmall || bAngYSmall || bAngZSmall)
|
||||
vdTheta.push_back( ANG_STRAIGHT) ;
|
||||
}
|
||||
// altrimenti arco di elica
|
||||
else {
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
DBLVECTOR vdPoly{ m_dRad * vtYRef.v[i] + dPitch * vtZRef.v[i],
|
||||
- 2 * m_dRad * vtXRef.v[i],
|
||||
- m_dRad * vtYRef.v[i] + dPitch * vtZRef.v[i]} ;
|
||||
DBLVECTOR vdRoot ;
|
||||
int nRoot = PolynomialRoots( 2, vdPoly, vdRoot) ;
|
||||
for ( int i = 0 ; i < nRoot ; ++ i) {
|
||||
double dAngDeg = atan2( 2 * vdRoot[i], (1 - vdRoot[i] * vdRoot[i])) * RADTODEG ;
|
||||
if ( abs( dAngDeg) > EPS_ANG_ZERO) {
|
||||
vdTheta.push_back( dAngDeg) ;
|
||||
vdTheta.push_back( dAngDeg + ANG_STRAIGHT) ;
|
||||
}
|
||||
else
|
||||
vdTheta.push_back( ANG_STRAIGHT) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// verifica degli angoli sull'arco ed eventuale considerazione dei punti
|
||||
for ( int i = 0 ; i < int( vdTheta.size()) ; ++ i) {
|
||||
double dTheta = ( vdTheta[i] > 0 ? vdTheta[i] : vdTheta[i] + ANG_FULL) ;
|
||||
if ( dTheta < abs( m_dAngCenDeg)) {
|
||||
Point3d ptP ;
|
||||
GetPointD1D2( dTheta / ( abs( m_dAngCenDeg)), FROM_MINUS, ptP) ;
|
||||
ptP.ToGlob( frRef) ;
|
||||
b3Ref.Add( ptP) ;
|
||||
}
|
||||
}
|
||||
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
|
||||
Vector3d vtFrExtr = m_VtExtr ;
|
||||
@@ -770,10 +825,10 @@ CurveArc::Validate( void)
|
||||
m_dAngCenDeg = - ANG_FULL ;
|
||||
}
|
||||
// eseguo il controllo
|
||||
m_nStatus = ( ( m_VtN.IsNormalized() && m_VtS.IsNormalized() &&
|
||||
AreOrthoApprox( m_VtN, m_VtS) &&
|
||||
m_dRad > EPS_SMALL && m_dRad < MAX_ARC_RAD &&
|
||||
abs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ;
|
||||
m_nStatus = ( ( m_PtCen.IsValid() &&
|
||||
m_VtN.IsNormalized() && m_VtS.IsNormalized() && AreOrthoApprox( m_VtN, m_VtS) &&
|
||||
m_dRad > EPS_SMALL && m_dRad < MAX_ARC_RAD &&
|
||||
abs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ;
|
||||
}
|
||||
|
||||
return ( m_nStatus == OK) ;
|
||||
@@ -828,7 +883,7 @@ CurveArc::GetEndPoint( Point3d& ptEnd) const
|
||||
double dAng = m_dAngCenDeg * DEGTORAD ;
|
||||
Vector3d vtDir = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ;
|
||||
ptEnd = m_PtCen + m_dRad * vtDir ;
|
||||
if ( abs( m_dDeltaN) > EPS_SMALL)
|
||||
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL)
|
||||
ptEnd += m_dDeltaN * m_VtN ;
|
||||
|
||||
return true ;
|
||||
@@ -846,7 +901,7 @@ CurveArc::GetMidPoint( Point3d& ptMid) const
|
||||
double dAng = 0.5 * m_dAngCenDeg * DEGTORAD ;
|
||||
Vector3d vtDir = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ;
|
||||
ptMid = m_PtCen + m_dRad * vtDir ;
|
||||
if ( abs( m_dDeltaN) > EPS_SMALL)
|
||||
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL)
|
||||
ptMid += ( 0.5 * m_dDeltaN) * m_VtN ;
|
||||
|
||||
return true ;
|
||||
@@ -874,7 +929,7 @@ CurveArc::GetCentroid( Point3d& ptCen) const
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_STD, PL))
|
||||
return false ;
|
||||
// calcolo il centro mediante PolygonPlane
|
||||
Point3d ptP ;
|
||||
@@ -896,17 +951,14 @@ CurveArc::GetDir( double dU, Vector3d& vtDir) const
|
||||
return false ;
|
||||
|
||||
// il parametro U deve essere compreso tra 0 e 1
|
||||
if ( dU < 0)
|
||||
dU = 0 ;
|
||||
else if ( dU > 1)
|
||||
dU = 1 ;
|
||||
dU = Clamp( dU, 0., 1.) ;
|
||||
|
||||
// versore al punto nel piano della circonferenza (ruoto m_VtS di dU * m_dAngCenDeg attorno a m_VtN)
|
||||
double dAng = dU * m_dAngCenDeg * DEGTORAD ;
|
||||
Vector3d vtRad = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ;
|
||||
// calcolo della tangente nel punto finale
|
||||
vtDir = ( m_dRad * m_dAngCenDeg * DEGTORAD) * ( m_VtN ^ vtRad) ;
|
||||
if ( abs( m_dDeltaN) > EPS_SMALL)
|
||||
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL)
|
||||
vtDir += m_dDeltaN * m_VtN ;
|
||||
// normalizzo
|
||||
return vtDir.Normalize( EPS_ZERO) ;
|
||||
@@ -921,10 +973,7 @@ CurveArc::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1, V
|
||||
return false ;
|
||||
|
||||
// il parametro U deve essere compreso tra 0 e 1
|
||||
if ( dU < 0)
|
||||
dU = 0 ;
|
||||
else if ( dU > 1)
|
||||
dU = 1 ;
|
||||
dU = Clamp( dU, 0., 1.) ;
|
||||
|
||||
// versore al punto nel piano della circonferenza (ruoto m_VtS di dU di m_dAngCenDeg attorno a m_VtN)
|
||||
double dAng = dU * m_dAngCenDeg * DEGTORAD ;
|
||||
@@ -932,13 +981,13 @@ CurveArc::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1, V
|
||||
|
||||
// calcolo del punto
|
||||
ptPos = m_PtCen + m_dRad * vtDir ;
|
||||
if ( abs( m_dDeltaN) > EPS_SMALL)
|
||||
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL)
|
||||
ptPos += ( dU * m_dDeltaN) * m_VtN ;
|
||||
|
||||
// calcolo della derivata prima
|
||||
if ( pvtDer1 != nullptr) {
|
||||
*pvtDer1 = ( m_dRad * m_dAngCenDeg * DEGTORAD) * ( m_VtN ^ vtDir) ;
|
||||
if ( abs( m_dDeltaN) > EPS_SMALL)
|
||||
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL)
|
||||
*pvtDer1 += m_dDeltaN * m_VtN ;
|
||||
}
|
||||
|
||||
@@ -960,7 +1009,7 @@ CurveArc::GetLength( double& dLen) const
|
||||
// lunghezza dell'arco piano
|
||||
dLen = m_dRad * abs( m_dAngCenDeg) * DEGTORAD ;
|
||||
// aggiunta eventuale parte ortogonale
|
||||
if ( abs( m_dDeltaN) > EPS_SMALL)
|
||||
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL)
|
||||
dLen = sqrt( dLen * dLen + m_dDeltaN * m_dDeltaN) ;
|
||||
|
||||
return ( dLen > EPS_SMALL) ;
|
||||
@@ -1201,7 +1250,7 @@ CurveArc::Invert( void)
|
||||
return false ;
|
||||
|
||||
// il centro va spostato di DeltaN
|
||||
if ( abs( m_dDeltaN) > EPS_SMALL)
|
||||
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL)
|
||||
m_PtCen += m_dDeltaN * m_VtN ;
|
||||
// il versore normale rimane inalterato
|
||||
// il versore iniziale diventa quello finale
|
||||
@@ -1372,13 +1421,11 @@ CurveArc::ModifyEnd( const Point3d& ptNewEnd)
|
||||
bool
|
||||
CurveArc::TrimStartAtParam( double dUTrim)
|
||||
{
|
||||
double dLen ;
|
||||
|
||||
|
||||
// riporto i parametri nel loro range
|
||||
dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
|
||||
dUTrim = Clamp( dUTrim, 0., 1.) ;
|
||||
|
||||
// recupero lunghezza
|
||||
double dLen ;
|
||||
if ( ! GetLength( dLen))
|
||||
return false ;
|
||||
|
||||
@@ -1390,13 +1437,11 @@ CurveArc::TrimStartAtParam( double dUTrim)
|
||||
bool
|
||||
CurveArc::TrimEndAtParam( double dUTrim)
|
||||
{
|
||||
double dLen ;
|
||||
|
||||
|
||||
// riporto i parametri nel loro range
|
||||
dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
|
||||
dUTrim = Clamp( dUTrim, 0., 1.) ;
|
||||
|
||||
// recupero lunghezza
|
||||
double dLen ;
|
||||
if ( ! GetLength( dLen))
|
||||
return false ;
|
||||
|
||||
@@ -1444,7 +1489,7 @@ CurveArc::TrimStartAtLen( double dLenTrim)
|
||||
dAngRot = m_dAngCenDeg * dLenTrim / dLen ;
|
||||
m_VtS.Rotate( m_VtN, dAngRot) ;
|
||||
m_dAngCenDeg -= dAngRot ;
|
||||
if ( abs( m_dDeltaN) > EPS_SMALL) {
|
||||
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL) {
|
||||
dMoveN = m_dDeltaN * dLenTrim / dLen ;
|
||||
m_PtCen.Translate( m_VtN * dMoveN) ;
|
||||
m_dDeltaN -= dMoveN ;
|
||||
@@ -1474,7 +1519,7 @@ CurveArc::TrimEndAtLen( double dLenTrim)
|
||||
// eseguo il trim
|
||||
if ( ( dLen - dLenTrim) > EPS_ZERO) {
|
||||
m_dAngCenDeg *= dLenTrim / dLen ;
|
||||
if ( abs( m_dDeltaN) > EPS_SMALL)
|
||||
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL)
|
||||
m_dDeltaN *= dLenTrim / dLen ;
|
||||
}
|
||||
|
||||
@@ -1753,11 +1798,14 @@ CurveArc::ToGlob( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1775,11 +1823,14 @@ CurveArc::ToLoc( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1800,11 +1851,14 @@ CurveArc::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// trasformo il centro e i versori
|
||||
return ( m_PtCen.LocToLoc( frOri, frDest) &&
|
||||
m_VtN.LocToLoc( frOri, frDest) &&
|
||||
@@ -1898,6 +1952,10 @@ CurveArc::ChangeRadius( double dNewRadius)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del raggio
|
||||
if ( ! ( dNewRadius > EPS_SMALL && dNewRadius < MAX_ARC_RAD))
|
||||
return false ;
|
||||
|
||||
// cambio il raggio
|
||||
m_dRad = dNewRadius ;
|
||||
|
||||
@@ -1936,6 +1994,10 @@ CurveArc::ChangeAngCenter( double dNewAngCenDeg)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico accettabilità angolo
|
||||
if ( ! ( abs( m_dAngCenDeg) > EPS_ANG_ZERO))
|
||||
return false ;
|
||||
|
||||
// cambio il parametro
|
||||
m_dAngCenDeg = dNewAngCenDeg ;
|
||||
|
||||
@@ -2028,10 +2090,6 @@ CurveArc::Flip( void)
|
||||
//----------------------------------------------------------------------------
|
||||
ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, bool bInside, const CurveArc& arArc)
|
||||
{
|
||||
int nStep ;
|
||||
double dAngStepDeg ;
|
||||
|
||||
|
||||
// inizializzazioni
|
||||
m_nTotPnt = 0 ;
|
||||
m_nCurrPnt = - 1 ;
|
||||
@@ -2049,6 +2107,7 @@ ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, bool bInside, const
|
||||
dAngTolDeg = min( dAngTolDeg, ANG_TOL_EXT_MAX_DEG) ;
|
||||
|
||||
// determinazione dello step angolare
|
||||
double dAngStepDeg ;
|
||||
double dLinTolRel = dLinTol / arArc.GetRadius() ;
|
||||
if ( bInside)
|
||||
dAngStepDeg = sqrt( 8 * dLinTolRel) * RADTODEG ;
|
||||
@@ -2057,7 +2116,7 @@ ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, bool bInside, const
|
||||
dAngStepDeg = min( dAngStepDeg, dAngTolDeg) ;
|
||||
|
||||
// dall'angolo al centro ricavo il numero di passi
|
||||
nStep = (int) ( abs( arArc.GetAngCenter()) / dAngStepDeg + 0.999) ;
|
||||
int nStep = int( abs( arArc.GetAngCenter()) / dAngStepDeg + 0.999) ;
|
||||
nStep = max( nStep, 1) ;
|
||||
|
||||
// sistemo lo step (per il numero intero di passi)
|
||||
@@ -2084,10 +2143,6 @@ ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, bool bInside, const
|
||||
bool
|
||||
ArcApproxer::GetPoint( double& dU, Point3d& ptP)
|
||||
{
|
||||
Vector3d vtA1p ;
|
||||
Vector3d vtA2p ;
|
||||
|
||||
|
||||
// incremento indice punto corrente
|
||||
++ m_nCurrPnt ;
|
||||
|
||||
@@ -2106,7 +2161,7 @@ ArcApproxer::GetPoint( double& dU, Point3d& ptP)
|
||||
if ( ! m_bInside && m_nCurrPnt == m_nTotPnt - 1) {
|
||||
dU = 1 ;
|
||||
ptP = m_PtCen + m_vtA1 * m_dRad ;
|
||||
if ( abs( m_dDeltaN) > EPS_SMALL)
|
||||
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL)
|
||||
ptP += ( dU * m_dDeltaN) * m_VtN ;
|
||||
return true ;
|
||||
}
|
||||
@@ -2118,8 +2173,8 @@ ArcApproxer::GetPoint( double& dU, Point3d& ptP)
|
||||
else
|
||||
dU = ( m_nCurrPnt - 0.5) / (double) ( m_nTotPnt - 2) ;
|
||||
// nuovo valore versori
|
||||
vtA1p = m_vtA1 ;
|
||||
vtA2p = m_vtA2 ;
|
||||
Vector3d vtA1p = m_vtA1 ;
|
||||
Vector3d vtA2p = m_vtA2 ;
|
||||
m_vtA1 = m_dCosA * vtA1p + m_dSinA * vtA2p ;
|
||||
m_vtA2 = - m_dSinA * vtA1p + m_dCosA * vtA2p ;
|
||||
// calcolo del punto
|
||||
@@ -2127,7 +2182,7 @@ ArcApproxer::GetPoint( double& dU, Point3d& ptP)
|
||||
ptP = m_PtCen + m_vtA1 * m_dRad ;
|
||||
else
|
||||
ptP = m_PtCen + ( vtA1p + m_vtA1) * ( m_dRad / ( 1 + m_dCosA)) ;
|
||||
if ( abs( m_dDeltaN) > EPS_SMALL)
|
||||
if ( abs( m_dDeltaN) > 0.1 * EPS_SMALL)
|
||||
ptP += ( dU * m_dDeltaN) * m_VtN ;
|
||||
|
||||
return true ;
|
||||
|
||||
+14
-9
@@ -49,10 +49,11 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // ICurve
|
||||
bool IsSimple( void) const override
|
||||
@@ -211,17 +212,21 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
double m_dDeltaN ; // variazione di quota lungo VtN della fine rispetto all'inizio
|
||||
Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN)
|
||||
double m_dThick ; // spessore
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveArc* CreateBasicCurveArc( void)
|
||||
{ return (static_cast<CurveArc*>( CreateGeoObj( CRV_ARC))) ; }
|
||||
{ return ( static_cast<CurveArc*>( CreateGeoObj( CRV_ARC))) ; }
|
||||
inline CurveArc* CloneBasicCurveArc( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_ARC)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveArc*>(pGObj->Clone())) ; }
|
||||
return ( static_cast<CurveArc*>( pGObj->Clone())) ; }
|
||||
inline const CurveArc* GetBasicCurveArc( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveArc*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_ARC)
|
||||
return nullptr ;
|
||||
return ( static_cast<const CurveArc*>( pGObj)) ; }
|
||||
inline CurveArc* GetBasicCurveArc( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveArc*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_ARC)
|
||||
return nullptr ;
|
||||
return ( static_cast<CurveArc*>( pGObj)) ; }
|
||||
|
||||
+208
-19
@@ -30,9 +30,8 @@ using namespace std ;
|
||||
bool
|
||||
IsClosed( const ICurve& crvC)
|
||||
{
|
||||
Point3d ptStart ;
|
||||
Point3d ptEnd ;
|
||||
return ( crvC.GetStartPoint( ptStart) && crvC.GetEndPoint( ptEnd) && AreSamePointApprox( ptStart, ptEnd)) ;
|
||||
Point3d ptStart, ptEnd ;
|
||||
return ( crvC.GetStartPoint( ptStart) && crvC.GetEndPoint( ptEnd) && AreSamePointApprox( ptStart, ptEnd)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -295,7 +294,7 @@ CurveGetAreaXY( const ICurve& crvC, double& dArea)
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ;
|
||||
// calcolo l'area
|
||||
double dAreaXY = 0 ;
|
||||
PL.GetAreaXY( dAreaXY) ;
|
||||
@@ -314,7 +313,7 @@ CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea)
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ;
|
||||
// calcolo l'area
|
||||
Plane3d plMyPlane ;
|
||||
double dMyArea = 0 ;
|
||||
@@ -365,9 +364,11 @@ CurveDump( const ICurve& crvC, string& sOut, bool bMM, const char* szNewLine)
|
||||
// altri dati per curva chiusa
|
||||
double dAreaXY ;
|
||||
if ( CurveGetAreaXY( crvC, dAreaXY)) {
|
||||
bool bCCW = ( dAreaXY > 0) ;
|
||||
bool bCCW = ( dAreaXY > 0) ;
|
||||
double dAreaUi = GetAreaInUiUnits( abs( dAreaXY), bMM) ;
|
||||
int nDec = ( dAreaUi > 100 ? 1 : ( dAreaUi > 0.1 ? 3 : 6)) ;
|
||||
sOut += string( "Closed") + ( bCCW ? " CCW" : " CW") + " AreaXY=" +
|
||||
ToString( GetAreaInUiUnits( abs( dAreaXY), bMM),1) + szNewLine ;
|
||||
ToString( dAreaUi, nDec) + szNewLine ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
@@ -509,14 +510,7 @@ CurveToArcsPerpExtrCurve( const ICurve* pCrv, double dLinTol, double dAngTolDeg)
|
||||
bool
|
||||
NurbsCurveCanonicalize( CNurbsData& cnData)
|
||||
{
|
||||
// se periodica
|
||||
if ( cnData.bPeriodic) {
|
||||
// va trasformata in non-periodica (clamped)
|
||||
// vedere The NurbsBook di Les Piegl e Tiller
|
||||
// mancano esempi per testare
|
||||
return false ;
|
||||
}
|
||||
// se con nodi extra
|
||||
// se con nodi extra
|
||||
if ( cnData.bExtraKnotes) {
|
||||
int nKnotesNbr = int( cnData.vU.size()) ;
|
||||
if ( nKnotesNbr < 4)
|
||||
@@ -525,7 +519,176 @@ NurbsCurveCanonicalize( CNurbsData& cnData)
|
||||
for ( int i = 0 ; i < nKnotesNbr - 2 ; ++ i)
|
||||
cnData.vU[i] = cnData.vU[i+1] ;
|
||||
cnData.vU.resize( nKnotesNbr - 2) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// se periodica
|
||||
if ( cnData.bPeriodic) {
|
||||
// va trasformata in non-periodica (clamped)
|
||||
// bisogna aumentare la molteplicità dei nodi u_p-1 e u_(m-p+1) fino ad arrivare al grado della nurbs
|
||||
// e poi scartare nodi e punti fuori dalla regione clamped ( al di fuori della regione u_p-1 -> u_(m-p+1))
|
||||
|
||||
// l'agoritmo per l'inserimento dei nodi l' A5.1 del libro delle Nurbs ( Piegl e Tiller), con qualche modifica
|
||||
// agli indici perché uso u_p-1 e u_(m-p+1), anziché u_p e u_m-p
|
||||
|
||||
// comincio ad aumentare la molteplictià del nodo u_m-p+1
|
||||
int nCP = int( cnData.vCP.size()) ;
|
||||
int nU = nCP + cnData.nDeg - 1 ;
|
||||
int nDeg = cnData.nDeg ;
|
||||
PNTVECTOR vBC ;
|
||||
vBC.resize( nDeg + 1) ;
|
||||
DBLVECTOR vBW ;
|
||||
vBW.resize( nDeg + 1) ;
|
||||
|
||||
// trovo il nodo di cui aumentare la molteplicità e ne calcolo la molteplicità
|
||||
int b = nU - nDeg - 1 +1;
|
||||
int i = b ;
|
||||
while ( abs( cnData.vU[b] - cnData.vU[b - 1]) < EPS_ZERO)
|
||||
-- b ;
|
||||
int mult = min( i - b + 1, nDeg) ; // mi aspetto che sia 1, ma comunque sarà < nDeg
|
||||
// recupero i punti da modificare
|
||||
if ( ! cnData.bRat) {
|
||||
for ( int i = 0 ; i <= nDeg - mult ; ++ i)
|
||||
vBC[i] = cnData.vCP[b - nDeg + 1 + i] ;
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= nDeg - mult ; ++ i) {
|
||||
vBC[i] = cnData.vCP[b - nDeg + 1 + i] * cnData.vW[b - nDeg + 1 + i] ;
|
||||
vBW[i] = cnData.vW[b - nDeg + 1 + i] ;
|
||||
}
|
||||
}
|
||||
|
||||
// salvo i punti inalterati
|
||||
int r = nDeg - mult ; // numero di volte che dovrò inserire il nodo
|
||||
cnData.vCP.resize( nCP + r) ;
|
||||
for ( int p = nCP - 1 ; p > b - mult ; --p) {
|
||||
cnData.vCP[r + p] = cnData.vCP[p] ;
|
||||
}
|
||||
if ( cnData.bRat ) {
|
||||
cnData.vW.resize( nCP + r) ;
|
||||
for ( int p = nCP - 1 ; p > b - mult ; --p) {
|
||||
cnData.vW[r + p] = cnData.vW[p] ;
|
||||
}
|
||||
}
|
||||
|
||||
// procedo all'inserimento
|
||||
int L = 0 ;
|
||||
double alpha ;
|
||||
double num, den ;
|
||||
if ( mult < nDeg) {
|
||||
// inserisco il nodo r volte
|
||||
for ( int j = 1 ; j <= r ; ++ j) {
|
||||
L = b - nDeg + j ;
|
||||
for ( int i = 0; i <= r - j ; ++i) {
|
||||
num = (cnData.vU[b] - cnData.vU[L + i]) ;
|
||||
den = ( cnData.vU[i + b + 1] - cnData.vU[L + i]) ;
|
||||
alpha = (cnData.vU[b] - cnData.vU[L + i])/ ( cnData.vU[i + b + 1] - cnData.vU[L + i]) ;
|
||||
vBC[i] = alpha * vBC[i +1 ] + ( 1 - alpha) * vBC[i] ;
|
||||
if ( cnData.bRat) {
|
||||
vBW[i] = alpha * vBW[i + 1] + ( 1 - alpha) * vBW[i] ;
|
||||
}
|
||||
}
|
||||
cnData.vCP[L + 1] = vBC[0] ;
|
||||
cnData.vCP[b + nDeg - j - mult] = vBC[r - j] ;
|
||||
if ( cnData.bRat ) {
|
||||
cnData.vW[L + 1] = vBW[0] ;
|
||||
cnData.vW[b + nDeg - j - mult] = vBW[r-j] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// allungo il vettore dei nodi e sposto gli ultimi nodi
|
||||
cnData.vU.resize(nU + r) ;
|
||||
for ( int p = nU - 1 ; p > b ; --p)
|
||||
cnData.vU[p + r] = cnData.vU[p] ;
|
||||
// aggiungo i nodi nuovi
|
||||
for ( int p = 0 ; p < r ; ++p)
|
||||
cnData.vU[b + 1 + p] = cnData.vU[b] ;
|
||||
nU = nU + r ;
|
||||
nCP = nCP + r ;
|
||||
|
||||
// aumento la molteplicità del punto u_p-1
|
||||
b = nDeg -1;
|
||||
i = b ;
|
||||
while ( abs( cnData.vU[b] - cnData.vU[b - 1]) < EPS_ZERO)
|
||||
-- b ;
|
||||
mult = min( i - b + 1, nDeg) ; // mi aspetto che sia 1, ma comunque sarà < cnData.nDeg
|
||||
// recupero i punti da modificare
|
||||
if ( ! cnData.bRat) {
|
||||
for ( int i = 0 ; i <= nDeg - mult ; ++ i)
|
||||
vBC[i] = cnData.vCP[i] ;
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= nDeg - mult ; ++ i) {
|
||||
vBC[i] = cnData.vCP[i] * cnData.vW[i] ;
|
||||
vBW[i] = cnData.vW[i] ;
|
||||
}
|
||||
}
|
||||
|
||||
r = nDeg - mult ;
|
||||
// salvo i punti inalterati
|
||||
cnData.vCP.resize( nCP + r) ;
|
||||
for ( int p = nCP - 1 ; p > b - mult ; --p) {
|
||||
cnData.vCP[r + p] = cnData.vCP[p] ;
|
||||
}
|
||||
if ( cnData.bRat ) {
|
||||
cnData.vW.resize( nCP + r) ;
|
||||
for ( int p = nCP - 1 ; p > b - mult ; --p) {
|
||||
cnData.vW[r + p] = cnData.vW[p] ;
|
||||
}
|
||||
}
|
||||
|
||||
// procedo all'inserimento
|
||||
L = 0 ;
|
||||
if ( mult < nDeg) {
|
||||
// inserisco il nodo r volte
|
||||
for ( int j = 1 ; j <= r ; ++ j) {
|
||||
L = b - nDeg + j ;
|
||||
for ( int i = 0; i <= r - j ; ++i) {
|
||||
alpha = (cnData.vU[b] - cnData.vU[L + i])/ ( cnData.vU[i + b + 1] - cnData.vU[L + i]) ;
|
||||
vBC[i] = alpha * vBC[i + 1] + ( 1 - alpha) * vBC[i] ;
|
||||
if ( cnData.bRat) {
|
||||
vBW[i] = alpha * vBW[i + 1] + ( 1 - alpha) * vBW[i] ;
|
||||
}
|
||||
}
|
||||
cnData.vCP[L + 1] = vBC[0] ;
|
||||
cnData.vCP[b + nDeg - j - mult] = vBC[r - j] ;
|
||||
if ( cnData.bRat ) {
|
||||
cnData.vW[L + 1] = vBW[0] ;
|
||||
cnData.vW[b + nDeg - j - mult] = vBW[r - j] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// allungo il vettore dei nodi e sposto gli ultimi nodi
|
||||
cnData.vU.resize(nU + r) ;
|
||||
for ( int p = nU - 1 ; p > b ; --p)
|
||||
cnData.vU[p+r] = cnData.vU[p] ;
|
||||
// aggiungo i nodi nuovi
|
||||
for ( int p = 0 ; p < r ; ++p)
|
||||
cnData.vU[b + 1 + p] = cnData.vU[b] ;
|
||||
nU = nU + r ;
|
||||
nCP = nCP + r ;
|
||||
|
||||
// rendo la curva chiusa e non periodica eliminando i primi e gli ultimi nDeg punti e nodi
|
||||
cnData.bPeriodic = false ;
|
||||
nCP = nCP - 2 * ( nDeg - 1);
|
||||
nU = nU - 2 * ( nDeg - 1);
|
||||
PNTVECTOR vCP_clamped ;
|
||||
vCP_clamped.resize( nCP) ;
|
||||
DBLVECTOR vU_clamped ;
|
||||
vU_clamped.resize( nU) ;
|
||||
for ( int i = 0 ; i < nCP ; ++i) {
|
||||
if ( ! cnData.bRat)
|
||||
vCP_clamped[i] = cnData.vCP[i + nDeg - 1] ;
|
||||
else
|
||||
vCP_clamped[i] = cnData.vCP[i + nDeg - 1] / cnData.vW[i + nDeg - 1] ;
|
||||
}
|
||||
cnData.vCP = vCP_clamped ;
|
||||
for ( int i = 0 ; i < nU ; ++i) {
|
||||
vU_clamped[i] = cnData.vU[i + nDeg - 1] ;
|
||||
}
|
||||
cnData.vU = vU_clamped ;
|
||||
|
||||
}
|
||||
|
||||
return true ;
|
||||
@@ -616,6 +779,7 @@ NurbsToBezierCurve( const CNurbsData& cnData)
|
||||
int b = cnData.nDeg ;
|
||||
bool bPrevRejected = false ;
|
||||
// ciclo
|
||||
int n = 0 ; // debug
|
||||
while ( b < nU - 1) {
|
||||
int i = b ;
|
||||
while ( b < nU - 1 && abs( cnData.vU[b+1] - cnData.vU[b]) < EPS_ZERO)
|
||||
@@ -683,7 +847,8 @@ NurbsToBezierCurve( const CNurbsData& cnData)
|
||||
pCrvBez.Reset() ;
|
||||
bPrevRejected = true ;
|
||||
}
|
||||
|
||||
// debug
|
||||
++n ;
|
||||
// inizializzazioni per la prossima curva di Bezier
|
||||
if ( b < nU - 1) {
|
||||
if ( ! cnData.bRat) {
|
||||
@@ -707,6 +872,30 @@ NurbsToBezierCurve( const CNurbsData& cnData)
|
||||
}
|
||||
}
|
||||
|
||||
// se la curva ha grado 1, manca da aggiungere l'ultimo tratto
|
||||
if ( cnData.nDeg == 1 ) {
|
||||
// costruisco la curva di Bezier e la inserisco nella curva composita
|
||||
PtrOwner<ICurveBezier> pCrvBez( CreateCurveBezier()) ;
|
||||
if ( ! pCrvBez->Init( cnData.nDeg, cnData.bRat))
|
||||
return nullptr ;
|
||||
if ( ! cnData.bRat) {
|
||||
for ( int i = 0 ; i <= cnData.nDeg ; ++ i) {
|
||||
if ( ! pCrvBez->SetControlPoint( i, vBC[i]))
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= cnData.nDeg ; ++ i) {
|
||||
if ( ! pCrvBez->SetControlPoint( i, vBC[i] / vBW[i], vBW[i]))
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
if ( ! pCrvBez->IsAPoint()) {
|
||||
if ( ! pCrvCompo->AddCurve( Release( pCrvBez)))
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
|
||||
// restituisco la curva composita
|
||||
return Release( pCrvCompo) ;
|
||||
}
|
||||
@@ -729,7 +918,7 @@ FlattenCurve( const ICurve& crCrv, double dToler, double dAngToler, int nFlag)
|
||||
return nullptr ;
|
||||
// Verifico se curva già piatta
|
||||
PolyLine PL ;
|
||||
if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||
if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL))
|
||||
return nullptr ;
|
||||
bool bFlat = true ;
|
||||
Plane3d plFlat ; plFlat.Set( ptCen, plMid.GetVersN()) ;
|
||||
@@ -790,7 +979,7 @@ ProjectCurveOnPlane( const ICurve& crCrv, const Plane3d& plPlane)
|
||||
{
|
||||
// determino se curva piana e suo eventuale piano
|
||||
Plane3d plCrv ;
|
||||
if ( crCrv.IsFlat( plCrv)) {
|
||||
if ( crCrv.IsFlat( plCrv, false, EPS_SMALL / 2)) {
|
||||
// se il piano della curva è parallelo a quello di proiezione
|
||||
if ( AreSameOrOppositeVectorExact( plCrv.GetVersN(), plPlane.GetVersN())) {
|
||||
// copio la curva
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EgkCurveAux.h"
|
||||
#include "/EgtDev/Include/EGkCurveAux.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool IsClosed( const ICurve& crvC) ;
|
||||
|
||||
+40
-11
@@ -45,8 +45,10 @@ GEOOBJ_REGISTER( CRV_BEZIER, NGE_C_BEZ, CurveBezier) ;
|
||||
//----------------------------------------------------------------------------
|
||||
CurveBezier::CurveBezier( void)
|
||||
: m_nStatus( TO_VERIFY), m_nDeg(), m_bRat( false), m_dParSing( -2),
|
||||
m_VtExtr(), m_dThick(), m_nTempProp()
|
||||
m_VtExtr(), m_dThick()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -264,7 +266,7 @@ CurveBezier::Clone( void) const
|
||||
bool
|
||||
CurveBezier::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const CurveBezier* pCB = dynamic_cast<const CurveBezier*>( pGObjSrc) ;
|
||||
const CurveBezier* pCB = GetBasicCurveBezier( pGObjSrc) ;
|
||||
if ( pCB == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pCB) ;
|
||||
@@ -283,7 +285,8 @@ CurveBezier::CopyFrom( const CurveBezier& cbSrc)
|
||||
m_vWeCtrl = cbSrc.m_vWeCtrl ;
|
||||
m_VtExtr = cbSrc.m_VtExtr ;
|
||||
m_dThick = cbSrc.m_dThick ;
|
||||
m_nTempProp = cbSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = cbSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = cbSrc.m_nTempProp[1] ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -421,6 +424,23 @@ CurveBezier::Load( NgeReader& ngeIn)
|
||||
bool
|
||||
CurveBezier::Validate( void)
|
||||
{
|
||||
if ( m_nStatus == TO_VERIFY) {
|
||||
for ( const auto& ptP : m_vPtCtrl) {
|
||||
if ( ! ptP.IsValid()) {
|
||||
m_nStatus = ERR ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( m_nStatus == TO_VERIFY) {
|
||||
for ( const auto& dWe : m_vWeCtrl) {
|
||||
if ( ! isfinite( dWe)) {
|
||||
m_nStatus = ERR ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_nStatus == TO_VERIFY)
|
||||
m_nStatus = ( ( m_nDeg > 0 && m_vPtCtrl.size() > 0) ? OK : ERR) ;
|
||||
|
||||
@@ -445,7 +465,7 @@ CurveBezier::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
|
||||
else {
|
||||
// costruisco una approssimazione lineare
|
||||
PolyLine PL ;
|
||||
if ( ! ApproxWithLines( LIN_TOL_MIN, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL))
|
||||
if ( ! ApproxWithLines( LIN_TOL_MIN, ANG_TOL_APPROX_DEG, APL_STD, PL))
|
||||
return false ;
|
||||
// ciclo sui punti della approssimazione
|
||||
Point3d ptTemp ;
|
||||
@@ -488,7 +508,7 @@ CurveBezier::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
else {
|
||||
// costruisco una approssimazione lineare
|
||||
PolyLine PL ;
|
||||
if ( ! ApproxWithLines( LIN_TOL_MIN, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL))
|
||||
if ( ! ApproxWithLines( LIN_TOL_MIN, ANG_TOL_APPROX_DEG, APL_STD, PL))
|
||||
return false ;
|
||||
// ciclo sui punti della approssimazione
|
||||
Point3d ptTemp ;
|
||||
@@ -615,7 +635,7 @@ CurveBezier::GetCentroid( Point3d& ptCen) const
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_STD, PL))
|
||||
return false ;
|
||||
// calcolo il centro mediante PolygonPlane
|
||||
Point3d ptP ;
|
||||
@@ -1426,7 +1446,7 @@ CurveBezier::ApproxWithArcsXY( double dLinTol, double dAngTolDeg, PolyArc& PA) c
|
||||
|
||||
// costruisco una approssimazione lineare
|
||||
PolyLine PL ;
|
||||
if ( ! ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, PL))
|
||||
if ( ! ApproxWithLines( dLinTol, dAngTolDeg, APL_STD, PL))
|
||||
return false ;
|
||||
|
||||
// approssimo la curva per approssimazioni successive mediante bisezione
|
||||
@@ -1475,7 +1495,7 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
|
||||
return false ;
|
||||
if ( ! pCC->FromPolyLine( PL))
|
||||
return false ;
|
||||
pCrv.Set( Release( pCC)) ;
|
||||
pCrv.Set( pCC) ;
|
||||
dMaxDist = 0 ;
|
||||
}
|
||||
// se la polilinea ha un solo punto, esco
|
||||
@@ -1971,11 +1991,14 @@ CurveBezier::ToGlob( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1995,11 +2018,14 @@ CurveBezier::ToLoc( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2019,11 +2045,14 @@ CurveBezier::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
|
||||
+14
-9
@@ -51,10 +51,11 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // ICurve
|
||||
bool IsSimple( void) const override { return true ; }
|
||||
@@ -189,17 +190,21 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo
|
||||
Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN)
|
||||
double m_dThick ; // spessore
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveBezier* CreateBasicCurveBezier( void)
|
||||
{ return (static_cast<CurveBezier*>( CreateGeoObj( CRV_BEZIER))) ; }
|
||||
{ return ( static_cast<CurveBezier*>( CreateGeoObj( CRV_BEZIER))) ; }
|
||||
inline CurveBezier* CloneBasicCurveBezier( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZIER)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveBezier*>(pGObj->Clone())) ; }
|
||||
return ( static_cast<CurveBezier*>( pGObj->Clone())) ; }
|
||||
inline const CurveBezier* GetBasicCurveBezier( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveBezier*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZIER)
|
||||
return nullptr ;
|
||||
return ( static_cast<const CurveBezier*>( pGObj)) ; }
|
||||
inline CurveBezier* GetBasicCurveBezier( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveBezier*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZIER)
|
||||
return nullptr ;
|
||||
return ( static_cast<CurveBezier*>( pGObj)) ; }
|
||||
|
||||
+69
-11
@@ -17,6 +17,7 @@
|
||||
#include "CalcDerivate.h"
|
||||
#include "BiArcs.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "RemoveCurveDefects.h"
|
||||
#include "/EgtDev/Include/EGkCurveByApprox.h"
|
||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||
#include "/EgtDev/Include/EGkPolyArc.h"
|
||||
@@ -56,28 +57,78 @@ ICurve*
|
||||
CurveByApprox::GetCurve( int nType, double dLinTol, double dAngTolDeg, double dLinFea)
|
||||
{
|
||||
// se da approssimare con archi
|
||||
if ( nType == ARCS_CORNER) {
|
||||
if ( nType == ARCS || nType == ARCS_CORNER) {
|
||||
// calcolo approssimazione
|
||||
PolyArc PA ;
|
||||
if ( ! GetArcs( dLinTol, dAngTolDeg, dLinFea, PA))
|
||||
return nullptr ;
|
||||
if ( nType == ARCS) {
|
||||
if ( ! GetArcs( dLinTol, dAngTolDeg, PA))
|
||||
return nullptr ;
|
||||
}
|
||||
else {
|
||||
if ( ! GetArcsCorner( dLinTol, dAngTolDeg, dLinFea, PA))
|
||||
return nullptr ;
|
||||
}
|
||||
// creo la composita formata da questa approssimazione
|
||||
PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ;
|
||||
if ( ! pCC->FromPolyArc( PA))
|
||||
return nullptr ;
|
||||
// elimino eventuali Small Z
|
||||
pCC->RemoveSmallDefects( dLinTol, dAngTolDeg) ;
|
||||
// eventuale fusione di curve compatibili
|
||||
pCC->MergeCurves( dLinTol, dAngTolDeg) ;
|
||||
// restituisco la curva
|
||||
return Release( pCC) ;
|
||||
}
|
||||
// altrimenti con curve di Bezier cubiche
|
||||
// !!! NON ANCORA IMPLEMENTATA !!!
|
||||
else if ( nType == CUBIC_BEZIERS) {
|
||||
// !!! NON ANCORA IMPLEMENTATA !!!
|
||||
return nullptr ;
|
||||
}
|
||||
// tipi non previsti
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveByApprox::GetArcs( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA)
|
||||
CurveByApprox::GetArcs( double dLinTol, double dAngTolDeg, PolyArc& PA)
|
||||
{
|
||||
// pulisco il poliarco
|
||||
PA.Clear() ;
|
||||
|
||||
// calcolo una parametrizzazione
|
||||
if ( ! CalcParameterization())
|
||||
return false ;
|
||||
|
||||
// calcolo le tangenti
|
||||
if ( ! CalcAkimaTangents( false))
|
||||
return false ;
|
||||
|
||||
// approssimo come unico tratto
|
||||
|
||||
// creo la polilinea che unisce i punti
|
||||
PolyLine PL ;
|
||||
int nPnt = int( m_vPnt.size()) ;
|
||||
for ( int j = 0 ; j < nPnt ; ++ j)
|
||||
PL.AddUPoint( j, m_vPnt[j]) ;
|
||||
// verifico se retta verticale
|
||||
BBox3d b3PL ;
|
||||
if ( ! PL.GetLocalBBox( b3PL))
|
||||
return false ;
|
||||
if ( b3PL.GetDimX() < EPS_SMALL && b3PL.GetDimY() < EPS_SMALL) {
|
||||
PA.AddUPoint( 0, m_vPnt[0], 0) ;
|
||||
PA.AddUPoint( nPnt - 1, m_vPnt[nPnt - 1], 0) ;
|
||||
}
|
||||
// altrimenti eseguo l'approssimazione con archi
|
||||
else {
|
||||
if ( ! BiArcOrSplit( 0, PL, dLinTol, dAngTolDeg, PA))
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveByApprox::GetArcsCorner( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA)
|
||||
{
|
||||
// pulisco il poliarco
|
||||
PA.Clear() ;
|
||||
@@ -102,9 +153,18 @@ CurveByApprox::GetArcs( double dLinTol, double dAngTolDeg, double dLinFea, PolyA
|
||||
PolyLine PL ;
|
||||
for ( int j = nPrev ; j <= m_vSplits[i] ; ++ j)
|
||||
PL.AddUPoint( j, m_vPnt[j]) ;
|
||||
// eseguo l'approssimazione con archi
|
||||
if ( ! BiArcOrSplit( 0, PL, dLinTol, dAngTolDeg, PA))
|
||||
// verifico se retta verticale
|
||||
BBox3d b3PL ;
|
||||
if ( ! PL.GetLocalBBox( b3PL))
|
||||
return false ;
|
||||
if ( b3PL.GetDimX() < EPS_SMALL && b3PL.GetDimY() < EPS_SMALL) {
|
||||
PA.AddUPoint( m_vSplits[i], m_vPnt[m_vSplits[i]], 0) ;
|
||||
}
|
||||
// altrimenti eseguo l'approssimazione con archi
|
||||
else {
|
||||
if ( ! BiArcOrSplit( 0, PL, dLinTol, dAngTolDeg, PA))
|
||||
return false ;
|
||||
}
|
||||
// salvo fine come prox inizio
|
||||
nPrev = m_vSplits[i] ;
|
||||
}
|
||||
@@ -453,11 +513,9 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
||||
return true ;
|
||||
// costruisco la retta che li unisce
|
||||
PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pCC))
|
||||
if ( IsNull( pCC) || ! pCC->FromPolyLine( PL))
|
||||
return false ;
|
||||
if ( ! pCC->FromPolyLine( PL))
|
||||
return false ;
|
||||
pCrv.Set( Release( pCC)) ;
|
||||
pCrv.Set( pCC) ;
|
||||
dMaxDist = 0 ;
|
||||
}
|
||||
// se la polilinea ha un solo punto, esco
|
||||
|
||||
+3
-3
@@ -15,9 +15,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "CalcDerivate.h"
|
||||
#include "/EgtDev/Include/EGkCurveByInterp.h"
|
||||
#include "/EgtDev/Include/EgkCurveComposite.h"
|
||||
#include "/EgtDev/Include/EgkBiArcs.h"
|
||||
#include "/EgtDev/Include/EgkCurveBezier.h"
|
||||
#include "/EgtDev/Include/EGkCurveComposite.h"
|
||||
#include "/EgtDev/Include/EGkBiArcs.h"
|
||||
#include "/EgtDev/Include/EGkCurveBezier.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
|
||||
|
||||
+387
-77
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2013
|
||||
// EgalTech 2013-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CurveComposite.cpp Data : 23.11.13 Versione : 1.3a1
|
||||
// File : CurveComposite.cpp Data : 23.01.22 Versione : 2.4a4
|
||||
// Contenuto : Implementazione della classe CCurveComposite.
|
||||
//
|
||||
//
|
||||
@@ -21,15 +21,17 @@
|
||||
#include "CurveBezier.h"
|
||||
#include "PolygonPlane.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "RemoveCurveDefects.h"
|
||||
#include "GeoConst.h"
|
||||
#include "GeoObjFactory.h"
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
#include "/EgtDev/Include/EGkCurveByApprox.h"
|
||||
#include "/EgtDev/Include/EgkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
|
||||
@@ -40,8 +42,10 @@ GEOOBJ_REGISTER( CRV_COMPO, NGE_C_CMP, CurveComposite) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveComposite::CurveComposite( void)
|
||||
: m_nStatus( TO_VERIFY), m_VtExtr(), m_dThick(), m_ptStart(), m_nTempProp(), m_Iter( m_CrvSmplS.end())
|
||||
: m_nStatus( TO_VERIFY), m_VtExtr(), m_dThick(), m_ptStart(), m_Iter( m_CrvSmplS.end())
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -63,7 +67,8 @@ CurveComposite::Clear( void)
|
||||
m_VtExtr = V_NULL ;
|
||||
m_dThick = 0 ;
|
||||
m_ptStart = ORIG ;
|
||||
m_nTempProp = 0 ;
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
m_Iter = m_CrvSmplS.end() ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
@@ -131,11 +136,9 @@ CurveComposite::AddCurve( ICurve* pCrv, bool bEndOrStart, double dLinTol)
|
||||
// altrimenti curva composita, devo aggiungere le singole curve semplici
|
||||
else {
|
||||
// riloco le curve dalla composita sorgente alla corrente
|
||||
CurveComposite* pCrvCompo = dynamic_cast<CurveComposite*>( pCrv) ;
|
||||
if ( ! AddCurveByRelocate( *pCrvCompo, bEndOrStart, dLinTol))
|
||||
PtrOwner<CurveComposite> pCrvCompo( GetBasicCurveComposite( pCrv)) ;
|
||||
if ( IsNull( pCrvCompo) || ! AddCurveByRelocate( *pCrvCompo, bEndOrStart, dLinTol))
|
||||
return false ;
|
||||
// cancello la curva composita originaria
|
||||
delete pCrvCompo ;
|
||||
}
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
@@ -205,8 +208,15 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
||||
if ( ! AreSamePointEpsilon( ptCrvStart, ptEnd, 0.01 * EPS_SMALL)) {
|
||||
// se in tolleranza, modifico l'inizio dell'entità
|
||||
if ( SqDist( ptCrvStart, ptEnd) < ( dLinTol * dLinTol)) {
|
||||
// lunghezza della curva originale
|
||||
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
||||
// eseguo modifica
|
||||
if ( ! pCrv->ModifyStart( ptEnd))
|
||||
return false ;
|
||||
// verifico che la lunghezza non sia variata troppo
|
||||
double dNewLen ; pCrv->GetLength( dNewLen) ;
|
||||
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
@@ -248,17 +258,28 @@ CurveComposite::Close( void)
|
||||
// verifico curva valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// se già chiusa, non faccio alcunché
|
||||
if ( IsClosed())
|
||||
return true ;
|
||||
// aggiungo la linea di chiusura
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
// determino la distanza tra gli estremi
|
||||
Point3d ptStart, ptEnd ;
|
||||
if ( ! GetStartPoint( ptStart) ||
|
||||
! GetEndPoint( ptEnd) ||
|
||||
! pLine->Set( ptEnd, ptStart) ||
|
||||
! AddSimpleCurve( Release( pLine)))
|
||||
! GetEndPoint( ptEnd))
|
||||
return false ;
|
||||
// se distanza inferiore al limite ridotto, non faccio alcunché
|
||||
if ( AreSamePointEpsilon( ptStart, ptEnd, EPS_SMALL / 10))
|
||||
return true ;
|
||||
// se molto vicini li modifico
|
||||
if ( AreSamePointEpsilon( ptStart, ptEnd, 10 * EPS_SMALL)) {
|
||||
Point3d ptMid = Media( ptStart, ptEnd) ;
|
||||
if ( ! ModifyStart( ptMid) ||
|
||||
! ModifyEnd( ptMid))
|
||||
return false ;
|
||||
}
|
||||
// altrimenti aggiungo la linea di chiusura
|
||||
else {
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( ! pLine->Set( ptEnd, ptStart) ||
|
||||
! AddSimpleCurve( Release( pLine)))
|
||||
return false ;
|
||||
}
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -541,7 +562,8 @@ CurveComposite::CopyFrom( const CurveComposite& ccSrc)
|
||||
Clear() ;
|
||||
m_VtExtr = ccSrc.m_VtExtr ;
|
||||
m_dThick = ccSrc.m_dThick ;
|
||||
m_nTempProp = ccSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = ccSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = ccSrc.m_nTempProp[1] ;
|
||||
for ( auto& pCrv : ccSrc.m_CrvSmplS) {
|
||||
if ( ! AddCurve( *pCrv))
|
||||
return false ;
|
||||
@@ -558,7 +580,8 @@ CurveComposite::RelocateFrom( CurveComposite& ccSrc)
|
||||
Clear() ;
|
||||
m_VtExtr = ccSrc.m_VtExtr ;
|
||||
m_dThick = ccSrc.m_dThick ;
|
||||
m_nTempProp = ccSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = ccSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = ccSrc.m_nTempProp[1] ;
|
||||
for ( ICurve* pCrv = ccSrc.RemoveFirstOrLastCurve( false) ;
|
||||
pCrv != nullptr ;
|
||||
pCrv = ccSrc.RemoveFirstOrLastCurve( false)) {
|
||||
@@ -826,9 +849,9 @@ CurveComposite::IsFlat( Plane3d& plPlane, bool bUseExtrusion, double dToler) con
|
||||
return false ;
|
||||
// ciclo sulle curve semplici (aggiungo solo eventuali punti intermedi e finali)
|
||||
int nCount = 0 ;
|
||||
for ( const ICurve* pCrv = GetFirstCurve() ;
|
||||
for ( const ICurve* pCrv = GetCurve( nCount) ;
|
||||
pCrv != nullptr ;
|
||||
pCrv = GetNextCurve(), ++ nCount) {
|
||||
pCrv = GetCurve( ++ nCount)) {
|
||||
switch ( pCrv->GetType()) {
|
||||
case CRV_LINE :
|
||||
// punto finale
|
||||
@@ -962,7 +985,7 @@ CurveComposite::GetCentroid( Point3d& ptCen) const
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||
if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_SPECIAL_INT, PL))
|
||||
return false ;
|
||||
// calcolo il centro mediante PolygonPlane
|
||||
Point3d ptP ;
|
||||
@@ -1011,7 +1034,7 @@ CurveComposite::GetMidDir( Vector3d& vtDir) const
|
||||
if ( ! GetLength( dLen) || ! GetParamAtLength( 0.5 * dLen, dMid))
|
||||
return false ;
|
||||
// calcolo la direzione
|
||||
return ::GetTang( *this, 0.5 * m_CrvSmplS.size(), FROM_MINUS, vtDir) ;
|
||||
return ::GetTang( *this, dMid, FROM_MINUS, vtDir) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1290,7 +1313,7 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
|
||||
dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ;
|
||||
|
||||
// se speciale, approssimo ogni singola entità e conservo le estremità interne (joint)
|
||||
if ( nType == APL_SPECIAL) {
|
||||
if ( nType == APL_SPECIAL || nType == APL_SPECIAL_INT) {
|
||||
// eseguo approssimazione
|
||||
double dStartPar = 0 ;
|
||||
for ( auto& pCrv : m_CrvSmplS) {
|
||||
@@ -1301,6 +1324,18 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
|
||||
PolyLine PLSmpl ;
|
||||
if ( ! pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, PLSmpl))
|
||||
return false ;
|
||||
// se richiesto almeno un punto interno con curve non rettilinee e ci sono solo gli estremi
|
||||
if ( nType == APL_SPECIAL_INT && pCrv->GetType() != CRV_LINE && PLSmpl.GetPointNbr() == 2) {
|
||||
// aggiungo il punto interno
|
||||
Point3d ptMid ;
|
||||
if ( ! pCrv->GetMidPoint( ptMid))
|
||||
return false ;
|
||||
double dU ;
|
||||
PLSmpl.GetLastU( dU) ;
|
||||
dU /= 2 ;
|
||||
PNTULIST& List = PLSmpl.GetUPointList() ;
|
||||
List.insert( ++ List.begin(), { ptMid, dU}) ;
|
||||
}
|
||||
// ripristino estrusione e spessore della curva semplice (annullandoli)
|
||||
pCrv->SetExtrusion( V_NULL) ;
|
||||
pCrv->SetThickness( 0) ;
|
||||
@@ -1316,8 +1351,8 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
|
||||
// se lineare con lato obbligato...
|
||||
if ( nType == APL_LEFT || nType == APL_LEFT_CONVEX ||
|
||||
nType == APL_RIGHT || nType == APL_RIGHT_CONVEX) {
|
||||
// prima approssimazione lineare a 10 * Epsilon
|
||||
if ( ! ApproxWithLines( 10 * EPS_SMALL, dAngTolDeg, APL_SPECIAL, PL))
|
||||
// prima approssimazione lineare alla tolleranza minima del programma
|
||||
if ( ! ApproxWithLines( EPS_SMALL, dAngTolDeg, APL_SPECIAL, PL))
|
||||
return false ;
|
||||
// eliminazione dei punti in tolleranza andando solo dalla parte ammessa
|
||||
Vector3d vtExtr = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ;
|
||||
@@ -1350,30 +1385,52 @@ CurveComposite::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// determino riferimento naturale della curva in base all'estrusione o al piano medio se questa è nulla
|
||||
Frame3d frNat ;
|
||||
if ( ! m_VtExtr.IsSmall()) {
|
||||
frNat.Set( ORIG, m_VtExtr) ;
|
||||
}
|
||||
else {
|
||||
Plane3d plPlane ;
|
||||
IsFlat( plPlane, false) ;
|
||||
if ( plPlane.IsValid()) {
|
||||
if ( plPlane.GetVersN().z < -EPS_ZERO)
|
||||
plPlane.Invert() ;
|
||||
frNat.Set( ORIG, plPlane.GetVersN()) ;
|
||||
}
|
||||
}
|
||||
|
||||
// eseguo approssimazione
|
||||
double dStartPar = 0 ;
|
||||
for ( auto& pCrv : m_CrvSmplS) {
|
||||
for ( const auto& pCrv : m_CrvSmplS) {
|
||||
// ne faccio una copia
|
||||
PtrOwner<ICurve> pCrvL( pCrv->Clone()) ;
|
||||
if ( IsNull( pCrvL))
|
||||
return false ;
|
||||
// assegno estrusione e spessore della curva composita
|
||||
pCrv->SetExtrusion( m_VtExtr) ;
|
||||
pCrv->SetThickness( m_dThick) ;
|
||||
pCrvL->SetExtrusion( m_VtExtr) ;
|
||||
pCrvL->SetThickness( m_dThick) ;
|
||||
// la porto nel riferimento naturale
|
||||
pCrvL->ToLoc( frNat) ;
|
||||
// recupero approssimazione per curva semplice
|
||||
PolyArc PASmpl ;
|
||||
if ( ! pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
|
||||
if ( ! pCrvL->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
|
||||
return false ;
|
||||
// la accodo opportunamente a quella della curva composita
|
||||
if ( ! PA.Join( PASmpl, dStartPar))
|
||||
return false ;
|
||||
// ripristino estrusione e spessore della curva semplice (annullandoli)
|
||||
pCrv->SetExtrusion( V_NULL) ;
|
||||
pCrv->SetThickness( 0) ;
|
||||
// incremento inizio parametro per prossima curva semplice
|
||||
dStartPar += 1 ;
|
||||
}
|
||||
|
||||
// riporto l'approssimazione nel riferimento della composita
|
||||
PA.ToGlob( frNat) ;
|
||||
|
||||
// assegno estrusione della curva composita
|
||||
PA.SetExtrusion( m_VtExtr) ;
|
||||
|
||||
return true ;
|
||||
// eliminazione dei punti in tolleranza (opportunamente diminuita)
|
||||
return PA.RemoveAlignedPoints( 0.5 * dLinTol) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1392,16 +1449,37 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
|
||||
double dMlStartPar = 0 ;
|
||||
CurveByApprox crvByApprox ;
|
||||
|
||||
// determino riferimento naturale della curva in base all'estrusione o al piano medio se questa è nulla
|
||||
Frame3d frNat ;
|
||||
if ( ! m_VtExtr.IsSmall()) {
|
||||
frNat.Set( ORIG, m_VtExtr) ;
|
||||
}
|
||||
else {
|
||||
Plane3d plPlane ;
|
||||
IsFlat( plPlane, false) ;
|
||||
if ( plPlane.IsValid()) {
|
||||
if ( plPlane.GetVersN().z < -EPS_ZERO)
|
||||
plPlane.Invert() ;
|
||||
frNat.Set( ORIG, plPlane.GetVersN()) ;
|
||||
}
|
||||
}
|
||||
|
||||
// eseguo approssimazione
|
||||
double dStartPar = 0 ;
|
||||
for ( auto& pCrv : m_CrvSmplS) {
|
||||
for ( const auto& pCrv : m_CrvSmplS) {
|
||||
// ne faccio una copia
|
||||
PtrOwner<ICurve> pCrvL( pCrv->Clone()) ;
|
||||
if ( IsNull( pCrvL))
|
||||
return false ;
|
||||
// assegno estrusione e spessore della curva composita
|
||||
pCrv->SetExtrusion( m_VtExtr) ;
|
||||
pCrv->SetThickness( m_dThick) ;
|
||||
pCrvL->SetExtrusion( m_VtExtr) ;
|
||||
pCrvL->SetThickness( m_dThick) ;
|
||||
// la porto nel riferimento naturale
|
||||
pCrvL->ToLoc( frNat) ;
|
||||
// se segmento di linea non feature
|
||||
double dLen ;
|
||||
if ( pCrv->GetType() == CRV_LINE && pCrv->GetLength( dLen) && dLen < dLinFea) {
|
||||
CurveLine* pLine = GetBasicCurveLine( pCrv) ;
|
||||
if ( pCrvL->GetType() == CRV_LINE && pCrvL->GetLength( dLen) && dLen < dLinFea) {
|
||||
CurveLine* pLine = GetBasicCurveLine( pCrvL) ;
|
||||
// se inizio di approx multilinea
|
||||
if ( ! bMultiLine) {
|
||||
bMultiLine = true ;
|
||||
@@ -1412,13 +1490,35 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
|
||||
// aggiungo il punto finale
|
||||
crvByApprox.AddPoint( pLine->GetEnd()) ;
|
||||
}
|
||||
// se altrimenti arco di circonferenza o curva di Bezier non feature
|
||||
else if ( ( pCrvL->GetType() == CRV_ARC || pCrvL->GetType() == CRV_BEZIER) &&
|
||||
pCrvL->GetLength( dLen) && dLen < dLinFea) {
|
||||
// se inizio di approx multilinea
|
||||
if ( ! bMultiLine) {
|
||||
bMultiLine = true ;
|
||||
dMlStartPar = dStartPar ;
|
||||
crvByApprox.Reset() ;
|
||||
Point3d ptStart ;
|
||||
if ( ! pCrvL->GetStartPoint( ptStart))
|
||||
return false ;
|
||||
crvByApprox.AddPoint( ptStart) ;
|
||||
}
|
||||
// aggiungo i punti opportunamente campionati sulla curva (compreso il finale)
|
||||
PolyLine PL ;
|
||||
if ( ! pCrvL->ApproxWithLines( dLinTol / 2, dAngTolDeg / 2, ICurve::APL_STD, PL))
|
||||
return false ;
|
||||
Point3d ptFin ;
|
||||
PL.GetFirstPoint( ptFin) ;
|
||||
while ( PL.GetNextPoint( ptFin))
|
||||
crvByApprox.AddPoint( ptFin) ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
// se in corso approx multilinee
|
||||
if ( bMultiLine) {
|
||||
bMultiLine = false ;
|
||||
PolyArc PASmpl ;
|
||||
if ( ! crvByApprox.GetArcs( dLinTol, dAngTolDeg, dLinFea, PASmpl))
|
||||
if ( ! crvByApprox.GetArcsCorner( dLinTol, dAngTolDeg, dLinFea, PASmpl))
|
||||
return false ;
|
||||
// la accodo opportunamente a quella della curva composita
|
||||
if ( ! PA.Join( PASmpl, dMlStartPar))
|
||||
@@ -1426,15 +1526,12 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
|
||||
}
|
||||
// recupero approssimazione per curva semplice
|
||||
PolyArc PASmpl ;
|
||||
if ( ! pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
|
||||
if ( ! pCrvL->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
|
||||
return false ;
|
||||
// la accodo opportunamente a quella della curva composita
|
||||
if ( ! PA.Join( PASmpl, dStartPar))
|
||||
return false ;
|
||||
}
|
||||
// ripristino estrusione e spessore della curva semplice (annullandoli)
|
||||
pCrv->SetExtrusion( V_NULL) ;
|
||||
pCrv->SetThickness( 0) ;
|
||||
// incremento inizio parametro per prossima curva semplice
|
||||
dStartPar += 1 ;
|
||||
}
|
||||
@@ -1442,18 +1539,21 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
|
||||
if ( bMultiLine) {
|
||||
bMultiLine = false ;
|
||||
PolyArc PASmpl ;
|
||||
if ( ! crvByApprox.GetArcs( dLinTol, dAngTolDeg, dLinFea, PASmpl))
|
||||
if ( ! crvByApprox.GetArcsCorner( dLinTol, dAngTolDeg, dLinFea, PASmpl))
|
||||
return false ;
|
||||
// la accodo opportunamente a quella della curva composita
|
||||
if ( ! PA.Join( PASmpl, dMlStartPar))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// riporto l'approssimazione nel riferimento della composita
|
||||
PA.ToGlob( frNat) ;
|
||||
|
||||
// assegno estrusione della curva composita
|
||||
PA.SetExtrusion( m_VtExtr) ;
|
||||
|
||||
// eliminazione dei punti in tolleranza
|
||||
return PA.RemoveAlignedPoints( dLinTol) ;
|
||||
// eliminazione dei punti in tolleranza (opportunamente diminuita)
|
||||
return PA.RemoveAlignedPoints( 0.5 * dLinTol) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1466,6 +1566,9 @@ CurveComposite::CopyParamRange( double dUStart, double dUEnd) const
|
||||
if ( dUStart < - EPS_PARAM || dUStart > dMaxU + EPS_PARAM ||
|
||||
dUEnd < - EPS_PARAM || dUEnd > dMaxU + EPS_PARAM)
|
||||
return nullptr ;
|
||||
// se i parametri coincidono, non resta alcunchè
|
||||
if ( abs( dUEnd - dUStart) < EPS_PARAM)
|
||||
return nullptr ;
|
||||
// se il parametro start supera quello di end
|
||||
if ( dUStart > dUEnd - EPS_PARAM) {
|
||||
// se curva aperta, il trim la cancella completamente quindi non resta alcunchè
|
||||
@@ -1497,7 +1600,7 @@ CurveComposite::CopyParamRange( double dUStart, double dUEnd) const
|
||||
// eseguo il trim della copia
|
||||
if ( ! pCopy->TrimStartEndAtParam( dUStart, dUEnd))
|
||||
return nullptr ;
|
||||
return ( ::Release( pCopy)) ;
|
||||
return ( pCopy->m_CrvSmplS.empty() ? nullptr : ::Release( pCopy)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1609,6 +1712,40 @@ CurveComposite::AddPoint( const Point3d& ptStart)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::AddLineTg( double dLen, bool bEndOrStart)
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// costruisco la linea
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pLine))
|
||||
return false ;
|
||||
// se da aggiungere alla fine
|
||||
if ( bEndOrStart) {
|
||||
Point3d ptEnd ;
|
||||
Vector3d vtEnd ;
|
||||
if ( ! GetEndPoint( ptEnd) || ! GetEndDir( vtEnd))
|
||||
return false ;
|
||||
Point3d ptNew = ptEnd + vtEnd * dLen ;
|
||||
if ( ! pLine->Set( ptEnd, ptNew))
|
||||
return false ;
|
||||
}
|
||||
// altrimenti da aggiungere all'inizio
|
||||
else {
|
||||
Point3d ptStart ;
|
||||
Vector3d vtStart ;
|
||||
if ( ! GetStartPoint( ptStart) || ! GetStartDir( vtStart))
|
||||
return false ;
|
||||
Point3d ptNew = ptStart - vtStart * dLen ;
|
||||
if ( ! pLine->Set( ptNew, ptStart))
|
||||
return false ;
|
||||
}
|
||||
return AddCurve( Release( pLine), bEndOrStart) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::AddLine( const Point3d& ptNew, bool bEndOrStart)
|
||||
@@ -1973,7 +2110,7 @@ CurveComposite::ModifyCurveToArc( int nCrv, const Point3d& ptMid)
|
||||
if ( nCrv < 0 || nCrv > nCrvCount - 1)
|
||||
return false ;
|
||||
// recupero la curva corrente
|
||||
ICurve* pCrv = *(m_CrvSmplS.begin() + nCrv) ;
|
||||
ICurve* pCrv = m_CrvSmplS[nCrv] ;
|
||||
// recupero gli estremi
|
||||
Point3d ptStart, ptEnd ;
|
||||
if ( ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetEndPoint( ptEnd))
|
||||
@@ -2006,7 +2143,7 @@ CurveComposite::ModifyCurveToLine( int nCrv)
|
||||
if ( nCrv < 0 || nCrv > nCrvCount - 1)
|
||||
return false ;
|
||||
// recupero la curva corrente
|
||||
ICurve* pCrv = *(m_CrvSmplS.begin() + nCrv) ;
|
||||
ICurve* pCrv = m_CrvSmplS[nCrv] ;
|
||||
// se già linea non devo fare alcunchè
|
||||
if ( pCrv->GetType() == CRV_LINE)
|
||||
return true ;
|
||||
@@ -2033,7 +2170,15 @@ CurveComposite::ModifyCurveToLine( int nCrv)
|
||||
bool
|
||||
CurveComposite::TrimStartAtParam( double dUTrim)
|
||||
{
|
||||
// ciclo sulle diverse curve dall'inizio
|
||||
// verifico validità parametro
|
||||
double dMaxU = double( m_CrvSmplS.size()) ;
|
||||
if ( dUTrim < -EPS_PARAM || dUTrim > dMaxU - EPS_PARAM)
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// ciclo sulle diverse curve dall'inizio
|
||||
double dUToTrim = dUTrim ;
|
||||
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
|
||||
// dominio parametrico della curva semplice
|
||||
@@ -2044,17 +2189,13 @@ CurveComposite::TrimStartAtParam( double dUTrim)
|
||||
// se lunghezza ancora da tagliare non nulla
|
||||
if ( dUToTrim > EPS_PARAM) {
|
||||
delete (*Iter) ;
|
||||
Iter ++ ;
|
||||
m_CrvSmplS.pop_front() ;
|
||||
Iter = m_CrvSmplS.erase( Iter) ;
|
||||
}
|
||||
// se lunghezza ancora da tagliare nulla (entro la tolleranza)
|
||||
else if ( dUToTrim > - EPS_PARAM ||
|
||||
! (*Iter)->TrimStartAtParam( 1 + dUToTrim)) {
|
||||
delete (*Iter) ;
|
||||
Iter ++ ;
|
||||
m_CrvSmplS.pop_front() ;
|
||||
if ( m_CrvSmplS.empty())
|
||||
return false ;
|
||||
Iter = m_CrvSmplS.erase( Iter) ;
|
||||
break ;
|
||||
}
|
||||
// altrimenti superata lunghezza ancora da tagliare (taglio già fatto al test sopra)
|
||||
@@ -2063,9 +2204,6 @@ CurveComposite::TrimStartAtParam( double dUTrim)
|
||||
}
|
||||
}
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -2073,6 +2211,14 @@ CurveComposite::TrimStartAtParam( double dUTrim)
|
||||
bool
|
||||
CurveComposite::TrimEndAtParam( double dUTrim)
|
||||
{
|
||||
// verifico validità parametro
|
||||
double dMaxU = double( m_CrvSmplS.size()) ;
|
||||
if ( dUTrim < EPS_PARAM || dUTrim > dMaxU + EPS_PARAM)
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// ciclo sulle diverse curve dalla fine
|
||||
bool bToErase = false ;
|
||||
double dUToTrim = dUTrim ;
|
||||
@@ -2114,9 +2260,6 @@ CurveComposite::TrimEndAtParam( double dUTrim)
|
||||
}
|
||||
}
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -2339,6 +2482,9 @@ CurveComposite::ExtendEndByLen( double dLenExt)
|
||||
bool
|
||||
CurveComposite::Translate( const Vector3d& vtMove)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2353,6 +2499,9 @@ CurveComposite::Translate( const Vector3d& vtMove)
|
||||
bool
|
||||
CurveComposite::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dell'asse di rotazione
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
@@ -2374,6 +2523,9 @@ CurveComposite::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAn
|
||||
bool
|
||||
CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico non sia nulla
|
||||
if ( abs( dCoeffX) < EPS_ZERO && abs( dCoeffY) < EPS_ZERO && abs( dCoeffZ) < EPS_ZERO)
|
||||
return false ;
|
||||
@@ -2458,6 +2610,9 @@ CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, dou
|
||||
bool
|
||||
CurveComposite::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del piano di specchiatura
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
@@ -2479,6 +2634,9 @@ CurveComposite::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
bool
|
||||
CurveComposite::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei parametri
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
@@ -2509,10 +2667,17 @@ CurveComposite::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector
|
||||
bool
|
||||
CurveComposite::ToGlob( const Frame3d& frRef)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2530,10 +2695,17 @@ CurveComposite::ToGlob( const Frame3d& frRef)
|
||||
bool
|
||||
CurveComposite::ToLoc( const Frame3d& frRef)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2551,6 +2723,9 @@ CurveComposite::ToLoc( const Frame3d& frRef)
|
||||
bool
|
||||
CurveComposite::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
@@ -2814,6 +2989,39 @@ CurveComposite::ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDe
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::StraightArcsToLines( double dLinTol, double dAngTolDeg)
|
||||
{
|
||||
// controllo le tolleranze
|
||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
||||
dAngTolDeg = Clamp( dAngTolDeg, EPS_ANG_SMALL, ANG_RIGHT) ;
|
||||
// verifico le singole curve
|
||||
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++ Iter) {
|
||||
CurveArc* pArc = GetBasicCurveArc( *Iter) ;
|
||||
if ( pArc != nullptr &&
|
||||
abs( pArc->GetAngCenter()) < dAngTolDeg &&
|
||||
pArc->GetRadius() * ( 1 - cos( pArc->GetAngCenter() / 2 * DEGTORAD)) < dLinTol) {
|
||||
// recupero gli estremi
|
||||
Point3d ptStart, ptEnd ;
|
||||
if ( ! pArc->GetStartPoint( ptStart) || ! pArc->GetEndPoint( ptEnd))
|
||||
return false ;
|
||||
// creo la linea
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pLine) || ! pLine->Set( ptStart, ptEnd))
|
||||
return false ;
|
||||
// elimino la curva originale e la sostituisco con la nuova
|
||||
delete (*Iter) ;
|
||||
(*Iter) = Release( pLine) ;
|
||||
}
|
||||
}
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int
|
||||
MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAngTol, bool bNeedSameProp)
|
||||
@@ -2839,9 +3047,11 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
}
|
||||
}
|
||||
// verifico compatibilità delle proprietà
|
||||
int nTprP = pCrvP->GetTempProp() ;
|
||||
int nTprC = pCrvC->GetTempProp() ;
|
||||
if ( bNeedSameProp && nTprP != nTprC)
|
||||
int nTpr0P = pCrvP->GetTempProp( 0) ;
|
||||
int nTpr0C = pCrvC->GetTempProp( 0) ;
|
||||
int nTpr1P = pCrvP->GetTempProp( 1) ;
|
||||
int nTpr1C = pCrvC->GetTempProp( 1) ;
|
||||
if ( bNeedSameProp && ( nTpr0P != nTpr0C || nTpr1P != nTpr1C))
|
||||
return 0 ;
|
||||
// coefficiente deduzione tolleranza
|
||||
const double COEFF_TOL = 0.7 ;
|
||||
@@ -2863,8 +3073,10 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
// diminuisco la tolleranza corrente dell'errore attuale
|
||||
dCurrLinTol -= COEFF_TOL * sqrt( dSqDist) ;
|
||||
// se curve originali con proprietà diversa, la cancello
|
||||
if ( nTprP != nTprC)
|
||||
pLineC->SetTempProp( 0) ;
|
||||
if ( nTpr0P != nTpr0C)
|
||||
pLineC->SetTempProp( 0, 0) ;
|
||||
if ( nTpr1P != nTpr1C)
|
||||
pLineC->SetTempProp( 0, 1) ;
|
||||
// torno flag modifica
|
||||
return -1 ;
|
||||
}
|
||||
@@ -2914,8 +3126,10 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0)
|
||||
NewArc.InvertN() ;
|
||||
// se curve originali con la stessa proprietà, la riporto
|
||||
if ( nTprP == nTprC)
|
||||
NewArc.SetTempProp( nTprC) ;
|
||||
if ( nTpr0P == nTpr0C)
|
||||
NewArc.SetTempProp( nTpr0C, 0) ;
|
||||
if ( nTpr1P == nTpr1C)
|
||||
NewArc.SetTempProp( nTpr1C, 1) ;
|
||||
// aggiorno l'arco corrente e torno flag modifica
|
||||
*pArcC = NewArc ;
|
||||
return -1 ;
|
||||
@@ -2937,8 +3151,10 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
CurveArc NewArc ;
|
||||
if ( NewArc.Set2PVN( ptP1, ptP3, vtDir1, pArcC->GetNormVersor())) {
|
||||
// se curve originali con la stessa proprietà, la riporto
|
||||
if ( nTprP == nTprC)
|
||||
NewArc.SetTempProp( nTprC) ;
|
||||
if ( nTpr0P == nTpr0C)
|
||||
NewArc.SetTempProp( nTpr0C, 0) ;
|
||||
if ( nTpr1P == nTpr1C)
|
||||
NewArc.SetTempProp( nTpr1C, 1) ;
|
||||
// aggiorno l'arco corrente e torno flag modifica
|
||||
*pArcC = NewArc ;
|
||||
return -1 ;
|
||||
@@ -3010,6 +3226,13 @@ CurveComposite::MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd,
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::RemoveSmallDefects( double dLinTol, double dAngTolDeg, bool bAlsoSpikes)
|
||||
{
|
||||
return (( ! bAlsoSpikes || RemoveCurveSpikes( this, dLinTol)) && RemoveCurveSmallZs(this, dLinTol)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
SplitTopBottomArcs( CurveComposite& cCompo)
|
||||
@@ -3129,7 +3352,7 @@ CurveComposite::RemoveUndercutOnY( double dLinTol, double dAngTolDeg)
|
||||
pSfrCut->Translate( b3Box.GetMin() - Point3d( 10 * EPS_SMALL, dLen, 0)) ;
|
||||
// calcolo la classificazione della curva rispetto alla regione
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ! pSfrCut->GetCurveClassification( *pOutLoop, ccClass))
|
||||
if ( ! pSfrCut->GetCurveClassification( *pOutLoop, EPS_SMALL, ccClass))
|
||||
return false ;
|
||||
// determino gli intervalli di curva da conservare
|
||||
Intervals inOk ;
|
||||
@@ -3243,7 +3466,94 @@ CurveComposite::IsACircle( double dLinTol, Point3d& ptCen, Vector3d& vtN, double
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::SetCurveTempProp( int nCrv, int nProp)
|
||||
CurveComposite::IsARectangle( double dLinTol, Point3d& ptP, Vector3d& vtL1, Vector3d& vtL2) const
|
||||
{
|
||||
// deve essere chiusa
|
||||
if ( ! IsClosed())
|
||||
return false ;
|
||||
// approssimo con segmenti di retta
|
||||
PolyLine PL ;
|
||||
if ( ! ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, APL_STD, PL))
|
||||
return false ;
|
||||
// deve giacere in un piano entro la tolleranza
|
||||
Plane3d plPlane ;
|
||||
if ( ! PL.IsFlat( plPlane, dLinTol))
|
||||
return false ;
|
||||
// deve essere formata da 4 segmenti
|
||||
if ( PL.GetLineNbr() != 4)
|
||||
return false ;
|
||||
// recupero i 4 vertici
|
||||
Point3d ptV1 ; PL.GetFirstPoint( ptV1) ;
|
||||
Point3d ptV2 ; PL.GetNextPoint( ptV2) ;
|
||||
Point3d ptV3 ; PL.GetNextPoint( ptV3) ;
|
||||
Point3d ptV4 ; PL.GetNextPoint( ptV4) ;
|
||||
// verifico che le diagonali si incontrino nel loro punto medio (-> è un parallelogramma)
|
||||
if ( ! AreSamePointEpsilon( Media( ptV1, ptV3), Media( ptV2, ptV4), dLinTol / 2))
|
||||
return false ;
|
||||
// verifico che le diagonali abbiano la stessa lunghezza (-> è un rettangolo)
|
||||
if ( abs( Dist( ptV1, ptV3) - Dist( ptV2, ptV4)) > dLinTol)
|
||||
return false ;
|
||||
// assegno i parametri del rettangolo
|
||||
ptP = ptV1 ;
|
||||
vtL1 = ptV2 - ptV1 ;
|
||||
vtL2 = ptV4 - ptV1 ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::IsATrapezoid( double dLinTol, Point3d& ptP, Vector3d& vtB1, Vector3d& vtL1, Vector3d& vtB2) const
|
||||
{
|
||||
// deve essere chiusa
|
||||
if ( ! IsClosed())
|
||||
return false ;
|
||||
// approssimo con segmenti di retta
|
||||
PolyLine PL ;
|
||||
if ( ! ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, APL_STD, PL))
|
||||
return false ;
|
||||
// deve giacere in un piano entro la tolleranza
|
||||
Plane3d plPlane ;
|
||||
if ( ! PL.IsFlat( plPlane, dLinTol))
|
||||
return false ;
|
||||
// deve essere formata da 4 segmenti
|
||||
if ( PL.GetLineNbr() != 4)
|
||||
return false ;
|
||||
// recupero i 4 vertici
|
||||
Point3d ptV1 ; PL.GetFirstPoint( ptV1) ;
|
||||
Point3d ptV2 ; PL.GetNextPoint( ptV2) ;
|
||||
Point3d ptV3 ; PL.GetNextPoint( ptV3) ;
|
||||
Point3d ptV4 ; PL.GetNextPoint( ptV4) ;
|
||||
// verifico se V4->V3 è parallelo a V1->V2
|
||||
double dV3B12, dV4B12 ;
|
||||
if ( ! DistPointLine( ptV3, ptV1, ptV2, false).GetDist( dV3B12) ||
|
||||
! DistPointLine( ptV4, ptV1, ptV2, false).GetDist( dV4B12))
|
||||
return false ;
|
||||
if ( abs( dV3B12 - dV4B12) < EPS_SMALL) {
|
||||
ptP = ptV1 ;
|
||||
vtB1 = ptV2 - ptV1 ;
|
||||
vtL1 = ptV4 - ptV1 ;
|
||||
vtB2 = ptV3 - ptV4 ;
|
||||
return true ;
|
||||
}
|
||||
// verifico se V1->V4 è parallelo a V2->V3
|
||||
double dV1B23, dV4B23 ;
|
||||
if ( ! DistPointLine( ptV1, ptV2, ptV3, false).GetDist( dV1B23) ||
|
||||
! DistPointLine( ptV4, ptV2, ptV3, false).GetDist( dV4B23))
|
||||
return false ;
|
||||
if ( abs( dV1B23 - dV4B23) < EPS_SMALL) {
|
||||
ptP = ptV2 ;
|
||||
vtB1 = ptV3 - ptV2 ;
|
||||
vtL1 = ptV1 - ptV2 ;
|
||||
vtB2 = ptV4 - ptV1 ;
|
||||
return true ;
|
||||
}
|
||||
// non è un trapezio
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::SetCurveTempProp( int nCrv, int nProp, int nPropNum)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
@@ -3252,13 +3562,13 @@ CurveComposite::SetCurveTempProp( int nCrv, int nProp)
|
||||
if ( nCrv < 0 || nCrv >= int( m_CrvSmplS.size()))
|
||||
return false ;
|
||||
// eseguo assegnazione
|
||||
m_CrvSmplS[nCrv]->SetTempProp( nProp) ;
|
||||
m_CrvSmplS[nCrv]->SetTempProp( nProp, nPropNum) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::GetCurveTempProp( int nCrv, int& nProp) const
|
||||
CurveComposite::GetCurveTempProp( int nCrv, int& nProp, int nPropNum) const
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
@@ -3267,6 +3577,6 @@ CurveComposite::GetCurveTempProp( int nCrv, int& nProp) const
|
||||
if ( nCrv < 0 || nCrv >= int( m_CrvSmplS.size()))
|
||||
return false ;
|
||||
// eseguo recupero
|
||||
nProp = m_CrvSmplS[nCrv]->GetTempProp() ;
|
||||
nProp = m_CrvSmplS[nCrv]->GetTempProp( nPropNum) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
+50
-14
@@ -1,12 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2021
|
||||
// EgalTech 2013-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CurveComposite.h Data : 03.04.21 Versione : 2.3d1
|
||||
// File : CurveComposite.h Data : 24.03.22 Versione : 2.4c2
|
||||
// Contenuto : Dichiarazione della classe Curva composita.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 16.04.13 DS Creazione modulo.
|
||||
// 24.03.22 DS Aggiunto metodo AddLineTg.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -50,10 +51,11 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // ICurve
|
||||
bool IsSimple( void) const override
|
||||
@@ -143,8 +145,9 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
bool ChangeStartPoint( double dU) override ;
|
||||
bool AddPoint( const Point3d& ptStart) override ;
|
||||
bool AddLine( const Point3d& ptNew, bool bEndOrStart = true) override ;
|
||||
bool AddArcTg( const Point3d& ptNew, bool bEndOrStart = true) override ;
|
||||
bool AddLineTg( double dLen, bool bEndOrStart = true) override ;
|
||||
bool AddArc2P( const Point3d& ptOther, const Point3d& ptNew, bool bEndOrStart = true) override ;
|
||||
bool AddArcTg( const Point3d& ptNew, bool bEndOrStart = true) override ;
|
||||
bool AddJoint( double dU) override ;
|
||||
bool ModifyJoint( int nU, const Point3d& ptNewJoint) override ;
|
||||
bool RemoveJoint( int nU) override ;
|
||||
@@ -153,13 +156,17 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
bool ModifyCurveToLine( int nCrv) override ;
|
||||
bool ArcsToBezierCurves( void) override ;
|
||||
bool ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDeg) override ;
|
||||
bool StraightArcsToLines( double dLinTol, double dAngTolDeg) override ;
|
||||
bool MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd = true, bool bNeedSameProp = false) override ;
|
||||
bool RemoveSmallDefects( double dLinTol, double dAngTolDeg, bool bAlsoSpikes = false) override ;
|
||||
bool RemoveUndercutOnY( double dLinTol, double dAngTolDeg) override ;
|
||||
bool IsAPoint( void) const override ;
|
||||
bool IsALine( double dLinTol, Point3d& ptStart, Point3d& ptEnd) const override ;
|
||||
bool IsACircle( double dLinTol, Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const override ;
|
||||
bool SetCurveTempProp( int nCrv, int nProp) override ;
|
||||
bool GetCurveTempProp( int nCrv, int& nProp) const override ;
|
||||
bool IsARectangle( double dLinTol, Point3d& ptP, Vector3d& vtL1, Vector3d& vtL2) const override ;
|
||||
bool IsATrapezoid( double dLinTol, Point3d& ptP, Vector3d& vtB1, Vector3d& vtL1, Vector3d& vtB2) const override ;
|
||||
bool SetCurveTempProp( int nCrv, int nProp, int nPropNum = 0) override ;
|
||||
bool GetCurveTempProp( int nCrv, int& nProp, int nPropNum = 0) const override ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
@@ -202,18 +209,47 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN)
|
||||
double m_dThick ; // spessore
|
||||
Point3d m_ptStart ; // punto iniziale per composita vuota per Add di linee o archi
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
mutable PCSD_CONST_ITER m_Iter ; // iteratore
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveComposite* CreateBasicCurveComposite( void)
|
||||
{ return (static_cast<CurveComposite*>( CreateGeoObj( CRV_COMPO))) ; }
|
||||
{ return ( static_cast<CurveComposite*>( CreateGeoObj( CRV_COMPO))) ; }
|
||||
inline CurveComposite* CloneBasicCurveComposite( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_COMPO)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveComposite*>(pGObj->Clone())) ; }
|
||||
return ( static_cast<CurveComposite*>( pGObj->Clone())) ; }
|
||||
inline const CurveComposite* GetBasicCurveComposite( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveComposite*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_COMPO)
|
||||
return nullptr ;
|
||||
return ( static_cast<const CurveComposite*>( pGObj)) ; }
|
||||
inline CurveComposite* GetBasicCurveComposite( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveComposite*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_COMPO)
|
||||
return nullptr ;
|
||||
return ( static_cast<CurveComposite*>( pGObj)) ; }
|
||||
inline CurveComposite* ConvertCurveToBasicComposite( IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || ( pGObj->GetType() & GEO_CURVE) == 0) {
|
||||
delete pGObj ;
|
||||
return nullptr ;
|
||||
}
|
||||
CurveComposite* pCrvCo = CreateBasicCurveComposite() ;
|
||||
if ( pCrvCo == nullptr) {
|
||||
delete pGObj ;
|
||||
return nullptr ;
|
||||
}
|
||||
ICurve* pCrv = static_cast<ICurve*>( pGObj) ;
|
||||
Vector3d vtExtr ;
|
||||
if ( pCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall())
|
||||
pCrvCo->SetExtrusion( vtExtr) ;
|
||||
double dThick ;
|
||||
if ( pCrv->GetThickness( dThick) && abs( dThick) > EPS_SMALL)
|
||||
pCrvCo->SetThickness( dThick) ;
|
||||
for ( int i = 0 ; i < 2 ; ++ i) {
|
||||
int nProp = pCrv->GetTempProp( i) ;
|
||||
if ( nProp != 0)
|
||||
pCrvCo->SetTempProp( nProp, i) ;
|
||||
}
|
||||
pCrvCo->AddCurve( pCrv) ;
|
||||
return pCrvCo ;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkCurve.h"
|
||||
#include "/EgtDev/Include/EgkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkCurve.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
+21
-10
@@ -19,6 +19,7 @@
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <new>
|
||||
|
||||
@@ -29,8 +30,10 @@ GEOOBJ_REGISTER( CRV_LINE, NGE_C_LIN, CurveLine) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveLine::CurveLine( void)
|
||||
: m_nStatus( TO_VERIFY), m_PtStart(), m_PtEnd(), m_VtExtr(), m_dThick(), m_nTempProp()
|
||||
: m_nStatus( TO_VERIFY), m_PtStart(), m_PtEnd(), m_VtExtr(), m_dThick()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -109,7 +112,7 @@ CurveLine::Clone( void) const
|
||||
bool
|
||||
CurveLine::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const CurveLine* pCL = dynamic_cast<const CurveLine*>( pGObjSrc) ;
|
||||
const CurveLine* pCL = GetBasicCurveLine( pGObjSrc) ;
|
||||
if ( pCL == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pCL) ;
|
||||
@@ -123,7 +126,8 @@ CurveLine::CopyFrom( const CurveLine& clSrc)
|
||||
return true ;
|
||||
m_VtExtr = clSrc.m_VtExtr ;
|
||||
m_dThick = clSrc.m_dThick ;
|
||||
m_nTempProp = clSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = clSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = clSrc.m_nTempProp[1] ;
|
||||
return Set( clSrc.m_PtStart, clSrc.m_PtEnd) ;
|
||||
}
|
||||
|
||||
@@ -256,7 +260,7 @@ bool
|
||||
CurveLine::Validate( void)
|
||||
{
|
||||
if ( m_nStatus == TO_VERIFY)
|
||||
m_nStatus = ( ! AreSamePointApprox( m_PtStart, m_PtEnd) ? OK : ERR) ;
|
||||
m_nStatus = ( m_PtStart.IsValid() && m_PtEnd.IsValid() && ! AreSamePointApprox( m_PtStart, m_PtEnd) ? OK : ERR) ;
|
||||
|
||||
return ( m_nStatus == OK) ;
|
||||
}
|
||||
@@ -353,10 +357,7 @@ CurveLine::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1,
|
||||
return false ;
|
||||
|
||||
// il parametro U deve essere compreso tra 0 e 1
|
||||
if ( dU < 0)
|
||||
dU = 0 ;
|
||||
else if ( dU > 1)
|
||||
dU = 1 ;
|
||||
dU = Clamp( dU, 0., 1.) ;
|
||||
|
||||
// calcolo del punto
|
||||
ptPos = Media( m_PtStart, m_PtEnd, dU) ;
|
||||
@@ -639,7 +640,7 @@ bool
|
||||
CurveLine::TrimStartAtParam( double dUTrim)
|
||||
{
|
||||
// riporto i parametri nel loro range
|
||||
dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
|
||||
dUTrim = Clamp( dUTrim, 0., 1.) ;
|
||||
|
||||
// recupero lunghezza
|
||||
double dLen ;
|
||||
@@ -655,7 +656,7 @@ bool
|
||||
CurveLine::TrimEndAtParam( double dUTrim)
|
||||
{
|
||||
// riporto i parametri nel loro range
|
||||
dUTrim = ( ( dUTrim < 0) ? 0 : (( dUTrim > 1) ? 1 : dUTrim)) ;
|
||||
dUTrim = Clamp( dUTrim, 0., 1.) ;
|
||||
|
||||
// recupero lunghezza
|
||||
double dLen ;
|
||||
@@ -784,6 +785,7 @@ CurveLine::Translate( const Vector3d& vtMove)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -916,6 +918,10 @@ CurveLine::ToGlob( const Frame3d& frRef)
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -934,6 +940,10 @@ CurveLine::ToLoc( const Frame3d& frRef)
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -951,6 +961,7 @@ CurveLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
+14
-9
@@ -49,10 +49,11 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // ICurve
|
||||
bool IsSimple( void) const override
|
||||
@@ -164,17 +165,21 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
Point3d m_PtEnd ; // punto finale
|
||||
Vector3d m_VtExtr ; // vettore estrusione
|
||||
double m_dThick ; // spessore
|
||||
int m_nTempProp ; // proprietŕ temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CurveLine* CreateBasicCurveLine( void)
|
||||
{ return (static_cast<CurveLine*>( CreateGeoObj( CRV_LINE))) ; }
|
||||
{ return ( static_cast<CurveLine*>( CreateGeoObj( CRV_LINE))) ; }
|
||||
inline CurveLine* CloneBasicCurveLine( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_LINE)
|
||||
return nullptr ;
|
||||
return (static_cast<CurveLine*>(pGObj->Clone())) ; }
|
||||
return ( static_cast<CurveLine*>( pGObj->Clone())) ; }
|
||||
inline const CurveLine* GetBasicCurveLine( const IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<const CurveLine*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_LINE)
|
||||
return nullptr ;
|
||||
return ( static_cast<const CurveLine*>( pGObj)) ; }
|
||||
inline CurveLine* GetBasicCurveLine( IGeoObj* pGObj)
|
||||
{ return (dynamic_cast<CurveLine*>(pGObj)) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != CRV_LINE)
|
||||
return nullptr ;
|
||||
return ( static_cast<CurveLine*>( pGObj)) ; }
|
||||
|
||||
+100
-96
@@ -1,13 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
// EgalTech 2020-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : DistLineLine.h Data : 06.11.20 Versione : 2.2k1
|
||||
// File : DistLineLine.h Data : 12.08.22 Versione : 2.4h1
|
||||
// Contenuto : Implementazione della classe distanza fra elementi lineari.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 06.11.20 LM Creazione modulo.
|
||||
//
|
||||
// 12.08.22 DS Correzioni e migliorie varie.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -18,22 +18,26 @@
|
||||
#include "/EgtDev/Include/EGkGeoConst.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DistLineLine::DistLineLine( const Point3d& ptSt1, const Point3d& ptEn1,
|
||||
const Point3d& ptSt2, const Point3d& ptEn2,
|
||||
bool bIsSegment1, bool bIsSegment2)
|
||||
{
|
||||
// reset oggetto
|
||||
m_dSqDist = - 1 ;
|
||||
m_dDist = - 1 ;
|
||||
// calcolo direzione segmenti
|
||||
Vector3d vtD1 = ptEn1 - ptSt1 ;
|
||||
double dLen1 = vtD1.Len() ;
|
||||
Vector3d vtD2 = ptEn2 - ptSt2 ;
|
||||
double dLen2 = vtD1.Len() ;
|
||||
if ( dLen1 < EPS_SMALL || dLen2 < EPS_SMALL) {
|
||||
m_dSqDist = - 1 ;
|
||||
m_dDist = - 1 ;
|
||||
double dLen2 = vtD2.Len() ;
|
||||
if ( dLen1 < EPS_SMALL || dLen2 < EPS_SMALL)
|
||||
return ;
|
||||
}
|
||||
vtD1 /= dLen1 ;
|
||||
vtD2 /= dLen2 ;
|
||||
// eseguo
|
||||
Calculate( ptSt1, vtD1, dLen1, ptSt2, vtD2, dLen2, bIsSegment1, bIsSegment2) ;
|
||||
}
|
||||
|
||||
@@ -43,11 +47,13 @@ DistLineLine::DistLineLine( const Point3d& ptSt1, const Vector3d& vtD1, double d
|
||||
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
|
||||
bool bIsSegment1, bool bIsSegment2)
|
||||
{
|
||||
if ( dLen1 < EPS_SMALL || dLen2 < EPS_SMALL) {
|
||||
m_dSqDist = - 1 ;
|
||||
m_dDist = - 1 ;
|
||||
// reset oggetto
|
||||
m_dSqDist = - 1 ;
|
||||
m_dDist = - 1 ;
|
||||
// verifico segmenti
|
||||
if ( dLen1 < EPS_SMALL || dLen2 < EPS_SMALL)
|
||||
return ;
|
||||
}
|
||||
// eseguo
|
||||
Calculate( ptSt1, vtD1, dLen1, ptSt2, vtD2, dLen2, bIsSegment1, bIsSegment2) ;
|
||||
}
|
||||
|
||||
@@ -57,6 +63,7 @@ DistLineLine::GetSqDist( double& dSqDist)
|
||||
{
|
||||
if ( m_dSqDist < 0)
|
||||
return false ;
|
||||
|
||||
dSqDist = m_dSqDist ;
|
||||
return true ;
|
||||
}
|
||||
@@ -67,7 +74,10 @@ DistLineLine::GetDist( double& dDist)
|
||||
{
|
||||
if ( m_dSqDist < 0)
|
||||
return false ;
|
||||
dDist = sqrt( m_dSqDist) ;
|
||||
|
||||
if ( m_dDist < 0)
|
||||
m_dDist = sqrt( m_dSqDist) ;
|
||||
dDist = m_dDist ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -84,55 +94,48 @@ DistLineLine::GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistLineLine::GetParamsAtMinDistPoints( double& dPar1, double& dPar2)
|
||||
DistLineLine::GetPositionsAtMinDistPoints( double& dPos1, double& dPos2)
|
||||
{
|
||||
if ( m_dSqDist < 0)
|
||||
return false ;
|
||||
dPar1 = m_dPar1 ;
|
||||
dPar2 = m_dPar2 ;
|
||||
dPos1 = m_dPos1 ;
|
||||
dPos2 = m_dPos2 ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Calcola la distanza fra i due elemnti lineari, i punti di minima distanza e
|
||||
// i loro rispettivi parametri.
|
||||
// Se la coppia di punti di minima distanza non è unica ne viene scelta una
|
||||
// in base a comodità di calcolo.
|
||||
// Calcola la distanza fra i due elementi lineari, i punti di minima distanza e le loro posizioni.
|
||||
// Se i due elementi sono paralleli i punti di minimo sono scelti secondo convenienza.
|
||||
void
|
||||
DistLineLine::Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1,
|
||||
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
|
||||
bool bIsSegment1, bool bIsSegment2)
|
||||
{
|
||||
// Caso di elementi lineari paralleli/antiparalleli
|
||||
// Se elementi paralleli o antiparalleli
|
||||
if ( AreSameOrOppositeVectorExact( vtD1, vtD2)) {
|
||||
// Almeno un elemento è una retta
|
||||
if ( ! ( bIsSegment1 && bIsSegment2)) {
|
||||
// Il primo elemento è segmento, quindi deve essere una retta il secondo
|
||||
if ( bIsSegment1) {
|
||||
Vector3d vtStSt = ptSt1 - ptSt2 ;
|
||||
double dLong = vtStSt * vtD2 ;
|
||||
Vector3d vtDist = vtStSt - dLong * vtD2 ;
|
||||
m_dSqDist = vtDist.SqLen() ;
|
||||
m_dDist = sqrt( m_dSqDist) ;
|
||||
m_dPar1 = 0 ;
|
||||
m_dPar2 = dLong ;
|
||||
m_ptMinDist1 = ptSt1 ;
|
||||
m_ptMinDist2 = ptSt2 + dLong * vtD2 ;
|
||||
}
|
||||
// Il primo elemento è una retta
|
||||
else {
|
||||
Vector3d vtStSt = ptSt2 - ptSt1 ;
|
||||
double dLong = vtStSt * vtD1 ;
|
||||
Vector3d vtDist = vtStSt - dLong * vtD1 ;
|
||||
m_dSqDist = vtDist.SqLen() ;
|
||||
m_dDist = sqrt( m_dSqDist) ;
|
||||
m_dPar1 = dLong ;
|
||||
m_dPar2 = 0 ;
|
||||
m_ptMinDist1 = ptSt1 + dLong * vtD1 ;
|
||||
m_ptMinDist2 = ptSt2 ;
|
||||
}
|
||||
// Se il primo elemento è una retta infinita
|
||||
if ( ! bIsSegment1) {
|
||||
Vector3d vtStSt = ptSt2 - ptSt1 ;
|
||||
double dLong = vtStSt * vtD1 ;
|
||||
Vector3d vtDist = vtStSt - dLong * vtD1 ;
|
||||
m_dSqDist = vtDist.SqLen() ;
|
||||
m_dPos1 = dLong ;
|
||||
m_dPos2 = 0 ;
|
||||
m_ptMinDist1 = ptSt1 + dLong * vtD1 ;
|
||||
m_ptMinDist2 = ptSt2 ;
|
||||
}
|
||||
// se altrimenti il secondo elemento è una retta infinita
|
||||
else if ( ! bIsSegment2) {
|
||||
Vector3d vtStSt = ptSt1 - ptSt2 ;
|
||||
double dLong = vtStSt * vtD2 ;
|
||||
Vector3d vtDist = vtStSt - dLong * vtD2 ;
|
||||
m_dSqDist = vtDist.SqLen() ;
|
||||
m_dPos1 = 0 ;
|
||||
m_dPos2 = dLong ;
|
||||
m_ptMinDist1 = ptSt1 ;
|
||||
m_ptMinDist2 = ptSt2 + dLong * vtD2 ;
|
||||
}
|
||||
// Entrambi gli elementi sono segmenti
|
||||
// altrimenti entrambi gli elementi sono segmenti
|
||||
else {
|
||||
Point3d ptEn1 = ptSt1 + dLen1 * vtD1 ;
|
||||
Point3d ptEn2 = ptSt2 + dLen2 * vtD2 ;
|
||||
@@ -140,7 +143,7 @@ DistLineLine::Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen
|
||||
Vector3d vtStEn = ptEn2 - ptSt1 ;
|
||||
double dStU = vtStSt * vtD1 ;
|
||||
double dEnU = vtStEn * vtD1 ;
|
||||
// Classifico i punti del segmento segmento in base alla loro
|
||||
// Classifico i punti del secondo segmento in base alla loro
|
||||
// coordinata rispetto all'ordinamento generato dal primo.
|
||||
double dMinPar, dMaxPar ;
|
||||
Point3d ptMinPar, ptMaxPar ;
|
||||
@@ -159,70 +162,71 @@ DistLineLine::Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen
|
||||
// Possibili posizioni reciproche dei segmenti
|
||||
if ( dMinPar > dLen1) {
|
||||
m_dSqDist = SqDist( ptEn1, ptMinPar) ;
|
||||
m_dDist = sqrt( m_dSqDist) ;
|
||||
m_ptMinDist1 = ptEn1 ;
|
||||
m_ptMinDist2 = ptMinPar ;
|
||||
m_dPar1 = dLen1 ;
|
||||
m_dPar2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
|
||||
m_dPos1 = dLen1 ;
|
||||
m_dPos2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
|
||||
}
|
||||
else if ( dMinPar > 0) {
|
||||
m_dSqDist = std::max( vtStSt * vtStSt - dStU * dStU, 0.) ;
|
||||
m_dDist = sqrt( m_dSqDist) ;
|
||||
m_dSqDist = max( vtStSt * vtStSt - dStU * dStU, 0.) ;
|
||||
m_ptMinDist1 = ptSt1 + dMinPar * vtD1 ;
|
||||
m_ptMinDist2 = ptMinPar ;
|
||||
m_dPar1 = dMinPar ;
|
||||
m_dPar2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
|
||||
m_dPos1 = dMinPar ;
|
||||
m_dPos2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
|
||||
}
|
||||
else if ( dMaxPar > 0) {
|
||||
m_dSqDist = std::max( vtStSt * vtStSt - dStU * dStU, 0.) ;
|
||||
m_dDist = sqrt( m_dSqDist) ;
|
||||
m_dSqDist = max( vtStSt * vtStSt - dStU * dStU, 0.) ;
|
||||
m_ptMinDist1 = ptSt1 ;
|
||||
m_ptMinDist2 = ptSt2 + ( ptSt1 - ptSt2) * vtD2 * vtD2 ;
|
||||
m_dPar1 = 0 ;
|
||||
m_dPar2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
|
||||
m_dPos1 = 0 ;
|
||||
m_dPos2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
|
||||
}
|
||||
else {
|
||||
m_dSqDist = SqDist( ptSt1, ptMaxPar) ;
|
||||
m_dDist = sqrt( m_dSqDist) ;
|
||||
m_ptMinDist1 = ptSt1 ;
|
||||
m_ptMinDist2 = ptMaxPar ;
|
||||
m_dPar1 = 0 ;
|
||||
m_dPar2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
|
||||
m_dPos1 = 0 ;
|
||||
m_dPos2 = Clamp( ( m_ptMinDist2 - ptSt2) * vtD2, 0., dLen2) ;
|
||||
}
|
||||
}
|
||||
return ;
|
||||
}
|
||||
// Caso generale
|
||||
Vector3d vtDist0 = ptSt2 - ptSt1 ;
|
||||
double dDist01 = vtDist0 * vtD1 ;
|
||||
double dDist02 = vtDist0 * vtD2 ;
|
||||
double dDotD1D2 = vtD1 * vtD2 ;
|
||||
double dT1 = dDist01 + ( ( dDist01 * dDotD1D2 - dDist02) * dDotD1D2) / ( 1 - dDotD1D2 * dDotD1D2) ;
|
||||
double dT2 = ( dDist01 * dDotD1D2 - dDist02) / ( 1 - dDotD1D2 * dDotD1D2) ;
|
||||
double dMin1 = - INFINITO ;
|
||||
double dMax1 = INFINITO ;
|
||||
double dMin2 = - INFINITO ;
|
||||
double dMax2 = INFINITO ;
|
||||
double dSt1On2 = ( ptSt1 - ptSt2) * vtD2 ;
|
||||
double dEn1On2 = ( ptSt1 + dLen1 * vtD1 - ptSt2) * vtD2 ;
|
||||
if ( bIsSegment1) {
|
||||
dMin1 = 0 ;
|
||||
dMax1 = dLen1 ;
|
||||
dMin2 = std::min( dSt1On2, dEn1On2) ;
|
||||
dMax2 = std::max( dSt1On2, dEn1On2) ;
|
||||
else {
|
||||
// Posizioni a distanza minima tra rette illimitate
|
||||
Vector3d vtStSt = ptSt2 - ptSt1 ;
|
||||
double dDist01 = vtStSt * vtD1 ;
|
||||
double dDist02 = vtStSt * vtD2 ;
|
||||
double dDotD1D2 = vtD1 * vtD2 ;
|
||||
double dT1 = ( dDist01 - dDotD1D2 * dDist02) / ( 1 - dDotD1D2 * dDotD1D2) ;
|
||||
double dT2 = ( dDotD1D2 * dDist01 - dDist02) / ( 1 - dDotD1D2 * dDotD1D2) ;
|
||||
// Posizioni minime e massime sui segmenti
|
||||
double dMin1 = ( bIsSegment1 ? 0 : -INFINITO) ;
|
||||
double dMax1 = ( bIsSegment1 ? dLen1 : INFINITO) ;
|
||||
double dMin2 = ( bIsSegment2 ? 0 : -INFINITO) ;
|
||||
double dMax2 = ( bIsSegment2 ? dLen2 : INFINITO) ;
|
||||
// Se entrambe le posizioni stanno nei segmenti
|
||||
if ( dT1 >= dMin1 && dT1 <= dMax1 && dT2 >= dMin2 && dT2 <= dMax2) {
|
||||
m_dPos1 = dT1 ;
|
||||
m_dPos2 = dT2 ;
|
||||
}
|
||||
// se altrimenti solo la prima sta nel segmento
|
||||
else if ( dT1 >= dMin1 && dT1 <= dMax1) {
|
||||
m_dPos2 = Clamp( dT2, dMin2, dMax2) ;
|
||||
m_dPos1 = Clamp( (( ptSt2 + m_dPos2 * vtD2) - ptSt1) * vtD1, dMin1, dMax1) ;
|
||||
}
|
||||
// se altrimenti solo la seconda sta nel segmento
|
||||
else if ( dT2 >= dMin2 && dT2 <= dMax2) {
|
||||
m_dPos1 = Clamp( dT1, dMin1, dMax1) ;
|
||||
m_dPos2 = Clamp( (( ptSt1 + m_dPos1 * vtD1) - ptSt2) * vtD2, dMin2, dMax2) ;
|
||||
}
|
||||
// altrimenti nessuna sta nel suo segmento
|
||||
else {
|
||||
m_dPos1 = Clamp( dT1, dMin1, dMax1) ;
|
||||
m_dPos2 = Clamp( (( ptSt1 + m_dPos1 * vtD1) - ptSt2) * vtD2, dMin2, dMax2) ;
|
||||
m_dPos1 = Clamp( (( ptSt2 + m_dPos2 * vtD2) - ptSt1) * vtD1, dMin1, dMax1) ;
|
||||
}
|
||||
m_ptMinDist1 = ptSt1 + m_dPos1 * vtD1 ;
|
||||
m_ptMinDist2 = ptSt2 + m_dPos2 * vtD2 ;
|
||||
m_dSqDist = SqDist( m_ptMinDist1, m_ptMinDist2) ;
|
||||
}
|
||||
if ( bIsSegment2) {
|
||||
double dSt2On1 = ( ptSt2 - ptSt1) * vtD1 ;
|
||||
double dEn2On1 = ( ptSt2 + dLen2 * vtD2 - ptSt1) * vtD1 ;
|
||||
dMin1 = std::max( dMin1, std::min( dSt2On1, dEn2On1)) ;
|
||||
dMax1 = std::min( dMax1, std::max( dSt2On1, dEn2On1)) ;
|
||||
dMin2 = std::max( dMin2, 0.) ;
|
||||
dMax2 = std::min( dMax2, dLen2) ;
|
||||
}
|
||||
m_dPar1 = Clamp( dT1, dMin1, dMax1) ;
|
||||
m_dPar2 = Clamp( dT2, dMin2, dMax2) ;
|
||||
m_ptMinDist1 = ptSt1 + m_dPar1 * vtD1 ;
|
||||
m_ptMinDist2 = ptSt2 + m_dPar2 * vtD2 ;
|
||||
m_dSqDist = SqDist( m_ptMinDist1, m_ptMinDist2) ;
|
||||
m_dDist = sqrt( m_dSqDist) ;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -37,17 +37,17 @@ class DistLineLine
|
||||
bool IsSmall( void) { return IsEpsilon( EPS_SMALL) ; }
|
||||
bool IsZero( void) { return IsEpsilon( EPS_ZERO) ; }
|
||||
bool GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2) ;
|
||||
bool GetParamsAtMinDistPoints( double& dPar1, double& dPar2) ;
|
||||
bool GetPositionsAtMinDistPoints( double& dPos1, double& dPos2) ;
|
||||
|
||||
private :
|
||||
void Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1,
|
||||
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
|
||||
bool bIsSegment1 = true, bool bIsSegment2 = true) ;
|
||||
bool bIsSegment1, bool bIsSegment2) ;
|
||||
private:
|
||||
double m_dSqDist ;
|
||||
double m_dDist ;
|
||||
double m_dPar1 ;
|
||||
double m_dPar2 ;
|
||||
double m_dPos1 ;
|
||||
double m_dPos2 ;
|
||||
Point3d m_ptMinDist1 ;
|
||||
Point3d m_ptMinDist2 ;
|
||||
} ;
|
||||
|
||||
+10
-11
@@ -23,33 +23,30 @@
|
||||
bool
|
||||
CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, double dLinTol, MDCVECTOR& vApproxMin)
|
||||
{
|
||||
double dSqDist ;
|
||||
double dPar ;
|
||||
double dUIni ;
|
||||
double dUFin ;
|
||||
Point3d ptIni ;
|
||||
Point3d ptFin ;
|
||||
double dMinDist ;
|
||||
double dSqMinDist ;
|
||||
MinDistCalc approxMin ;
|
||||
|
||||
vApproxMin.reserve( 4) ;
|
||||
vApproxMin.clear() ;
|
||||
|
||||
bool bFound = false ;
|
||||
bool bOnEnd = false ;
|
||||
vApproxMin.reserve( 4) ;
|
||||
vApproxMin.clear() ;
|
||||
double dUIni, dUFin ;
|
||||
Point3d ptIni, ptFin ;
|
||||
double dMinDist, dSqMinDist ;
|
||||
for ( bool bLine = PL.GetFirstULine( &dUIni, &ptIni, &dUFin, &ptFin) ;
|
||||
bLine ;
|
||||
bLine = PL.GetNextULine( &dUIni, &ptIni, &dUFin, &ptFin)) {
|
||||
// calcolo la distanza del punto dal segmento
|
||||
DistPointLine dstPtLn( ptP, ptIni, ptFin) ;
|
||||
double dSqDist ;
|
||||
if ( ! dstPtLn.GetSqDist( dSqDist))
|
||||
continue ;
|
||||
// altro punto con la stessa minima distanza già trovata
|
||||
if ( bFound && abs( dSqDist - dSqMinDist) < 2 * dMinDist * dLinTol) {
|
||||
// salvo i dati nella struttura
|
||||
MinDistCalc approxMin ;
|
||||
approxMin.dDist = dMinDist ;
|
||||
dstPtLn.GetMinDistPoint( approxMin.ptQ) ;
|
||||
double dPar ;
|
||||
dstPtLn.GetParamAtMinDistPoint( dPar) ;
|
||||
approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ;
|
||||
approxMin.dParMin = dUIni ;
|
||||
@@ -66,8 +63,10 @@ CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, double dLinTol, MDCV
|
||||
dSqMinDist = dSqDist ;
|
||||
dMinDist = sqrt( dSqMinDist) ;
|
||||
// salvo i dati nella struttura
|
||||
MinDistCalc approxMin ;
|
||||
approxMin.dDist = dMinDist ;
|
||||
dstPtLn.GetMinDistPoint( approxMin.ptQ) ;
|
||||
double dPar ;
|
||||
dstPtLn.GetParamAtMinDistPoint( dPar) ;
|
||||
approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ;
|
||||
approxMin.dParMin = dUIni ;
|
||||
|
||||
@@ -89,8 +89,18 @@ DistPointCrvComposite::DistPointCrvComposite( const Point3d& ptP, const ICurveCo
|
||||
}
|
||||
}
|
||||
// altrimenti aggiungo
|
||||
else
|
||||
m_Info.push_back( aInfo) ;
|
||||
else {
|
||||
if ( dCurrDist < m_dDist) {
|
||||
// aggiorno i minimi
|
||||
m_dDist = dCurrDist ;
|
||||
// inserisco in testa
|
||||
m_Info.insert( m_Info.begin(), aInfo) ;
|
||||
}
|
||||
else {
|
||||
// inserisco in coda
|
||||
m_Info.push_back( aInfo) ;
|
||||
}
|
||||
}
|
||||
// passo al successivo
|
||||
++ i ;
|
||||
}
|
||||
|
||||
+105
-21
@@ -12,6 +12,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||
|
||||
@@ -24,7 +25,7 @@ using namespace std ;
|
||||
// I casi in cui non vengono trovati box di misura positiva sono quelli in cui o il box A è contenuto
|
||||
// nel box B; uno di questi si verifica se il box A è vuoto.
|
||||
// Nel vettore vBoxDiff vengono restituiti i box la cui unione costituisce la differenza fra A e B.
|
||||
bool
|
||||
static bool
|
||||
BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDiff)
|
||||
{
|
||||
// Svuoto il risultato
|
||||
@@ -93,30 +94,33 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
// Inizializzo distanza non calcolata
|
||||
m_dDist = - 1. ;
|
||||
|
||||
// Lavoro con l'oggetto superficie trimesh di base
|
||||
const SurfTriMesh* pStm = GetBasicSurfTriMesh( &tmSurf) ;
|
||||
if ( pStm == nullptr)
|
||||
return ;
|
||||
|
||||
// Recupero e verifico il box locale della superficie
|
||||
BBox3d b3Stm = tmSurf.GetAllTriaBox() ;
|
||||
BBox3d b3Stm = pStm->GetAllTriaBox() ;
|
||||
if ( b3Stm.IsEmpty())
|
||||
return ;
|
||||
|
||||
// Determino i triangoli vicini e fra di essi cerco quello di minima distanza.
|
||||
// Considero un box centrato nel punto P; finché all'interno del box non trovo un set di triangoli
|
||||
// fra cui quello a distanza minima dal punto P ha distanza minore del minimo semi-lato del box,
|
||||
// continuo a ingrandire il box. La condizione di terminazione garantisce di trovare il tiangolo di
|
||||
// distanza minima della trimesh intera.
|
||||
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate.
|
||||
// Termino quando non trovo più triangoli che possano soddisfare la richiesta.
|
||||
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
|
||||
double dDeltaLen = max( min( min( ptMax.x - ptMin.x, ptMax.y - ptMin.y), ptMax.z - ptMin.z) / 40., 10.) ;
|
||||
double dDeltaLen = max( min( min( b3Stm.GetDimX(), b3Stm.GetDimY()), b3Stm.GetDimZ()) / 40., 20.) ;
|
||||
double dBoxHalfLenX = max( max( ptMin.x - ptP.x, ptP.x - ptMax.x), 0.) + dDeltaLen ;
|
||||
double dBoxHalfLenY = max( max( ptMin.y - ptP.y, ptP.y - ptMax.y), 0.) + dDeltaLen ;
|
||||
double dBoxHalfLenZ = max( max( ptMin.z - ptP.z, ptP.z - ptMax.z), 0.) + dDeltaLen ;
|
||||
// Considero anche il box precedente per poter analizzare solo lo spazio differenza tra i due
|
||||
// Considero anche il box precedente per poter analizzare solo il volume differenza tra i due
|
||||
BBox3d boxPPrev( ptP) ;
|
||||
BBox3d boxP( ptP, dBoxHalfLenX, dBoxHalfLenY, dBoxHalfLenZ) ;
|
||||
// Variabili distanza minima, indice del triangolo di distanza minima, punto di distanza minima
|
||||
double dMinSqDist = DBL_MAX ;
|
||||
int nMinDistTriaIndex = SVT_NULL ;
|
||||
Point3d ptMinDistPoint ;
|
||||
bool bContinue = true ;
|
||||
// Finché non si verifica la condizione di terminazione ingrandisco il box.
|
||||
pStm->ResetTempInts() ;
|
||||
bool bContinue = true ;
|
||||
while ( bContinue) {
|
||||
// Calcolo il box differenza con il precedente per non esplorare parti già considerate
|
||||
BOXVECTOR vBox ;
|
||||
@@ -131,18 +135,21 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
// ricerca sui triangoli nel box
|
||||
bCollide = true ;
|
||||
INTVECTOR vnIds ;
|
||||
if ( tmSurf.GetAllTriaOverlapBox( b3Int, vnIds)) {
|
||||
if ( pStm->GetAllTriaOverlapBox( b3Int, vnIds)) {
|
||||
// Ciclo sui triangoli del sotto-box corrente
|
||||
for ( auto nT : vnIds) {
|
||||
int nTriaTemp ;
|
||||
Triangle3d trCurTria ;
|
||||
tmSurf.GetTriangle( nT, trCurTria) ;
|
||||
DistPointTriangle distPT( ptP, trCurTria) ;
|
||||
double dCurSqDist ;
|
||||
// Se la distanza del triangolo è valida e minore di quella attuale aggiorno
|
||||
if ( distPT.GetSqDist( dCurSqDist) && dCurSqDist < dMinSqDist) {
|
||||
dMinSqDist = dCurSqDist ;
|
||||
nMinDistTriaIndex = nT ;
|
||||
distPT.GetMinDistPoint( ptMinDistPoint) ;
|
||||
if ( pStm->GetTempInt( nT, nTriaTemp) && nTriaTemp == 0 && pStm->GetTriangle( nT, trCurTria)) {
|
||||
pStm->SetTempInt( nT, 1) ;
|
||||
DistPointTriangle distPT( ptP, trCurTria) ;
|
||||
double dCurSqDist ;
|
||||
// Se la distanza del triangolo è valida e minore di quella attuale aggiorno
|
||||
if ( distPT.GetSqDist( dCurSqDist) && dCurSqDist < dMinSqDist) {
|
||||
dMinSqDist = dCurSqDist ;
|
||||
nMinDistTriaIndex = nT ;
|
||||
distPT.GetMinDistPoint( ptMinDistPoint) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,9 +168,9 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
m_nMinDistTriaIndex = nMinDistTriaIndex ;
|
||||
m_ptMinDistPoint = ptMinDistPoint ;
|
||||
Triangle3d trMinDistTria ;
|
||||
tmSurf.GetTriangle( m_nMinDistTriaIndex, trMinDistTria) ;
|
||||
pStm->GetTriangle( m_nMinDistTriaIndex, trMinDistTria) ;
|
||||
trMinDistTria.Validate() ;
|
||||
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * trMinDistTria.GetN() < - EPS_SMALL) && tmSurf.IsClosed() ;
|
||||
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * trMinDistTria.GetN() < - EPS_SMALL) && pStm->IsClosed() ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,3 +209,80 @@ DistPointSurfTm::GetMinDistTriaIndex( int& nMinDistIndex)
|
||||
nMinDistIndex = m_nMinDistTriaIndex ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
{
|
||||
// Lavoro con l'oggetto superficie trimesh di base
|
||||
const SurfTriMesh* pStm = GetBasicSurfTriMesh( &tmSurf) ;
|
||||
if ( pStm == nullptr)
|
||||
return SVT_NULL ;
|
||||
|
||||
// Recupero e verifico il box locale della superficie
|
||||
BBox3d b3Stm = pStm->GetAllTriaBox() ;
|
||||
if ( b3Stm.IsEmpty())
|
||||
return SVT_NULL ;
|
||||
|
||||
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate.
|
||||
// Termino quando non trovo più triangoli che possano soddisfare la richiesta.
|
||||
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
|
||||
double dDeltaLen = max( min( min( b3Stm.GetDimX(), b3Stm.GetDimY()), b3Stm.GetDimZ()) / 40., 20.) ;
|
||||
double dBoxHalfLenX = max( max( ptMin.x - ptP.x, ptP.x - ptMax.x), 0.) + dDeltaLen ;
|
||||
double dBoxHalfLenY = max( max( ptMin.y - ptP.y, ptP.y - ptMax.y), 0.) + dDeltaLen ;
|
||||
double dBoxHalfLenZ = max( max( ptMin.z - ptP.z, ptP.z - ptMax.z), 0.) + dDeltaLen ;
|
||||
// Considero anche il box precedente per poter analizzare solo il volume differenza tra i due
|
||||
BBox3d boxPPrev( ptP) ;
|
||||
BBox3d boxP( ptP, dBoxHalfLenX, dBoxHalfLenY, dBoxHalfLenZ) ;
|
||||
// Variabili distanza minima
|
||||
int nVert = SVT_NULL ;
|
||||
double dMinSqDist = DBL_MAX ;
|
||||
// Finché non si verifica la condizione di terminazione ingrandisco il box.
|
||||
pStm->ResetTempInts() ;
|
||||
bool bContinue = true ;
|
||||
while ( bContinue) {
|
||||
// Calcolo il box differenza con il precedente per non esplorare parti già considerate
|
||||
BOXVECTOR vBox ;
|
||||
BoundingBoxDifference( boxP, boxPPrev, vBox) ;
|
||||
// Ciclo sui box differenza
|
||||
bool bCollide = false ;
|
||||
for ( const auto& b3Box : vBox) {
|
||||
// interseco il box con quello della superficie e ne verifico la distanza minima dal punto
|
||||
BBox3d b3Int ;
|
||||
if ( ! b3Box.FindIntersection( b3Stm, b3Int) || b3Int.SqDistFromPoint( ptP) > dMinSqDist)
|
||||
continue ;
|
||||
// ricerca sui triangoli nel box
|
||||
bCollide = true ;
|
||||
INTVECTOR vnIds ;
|
||||
if ( pStm->GetAllTriaOverlapBox( b3Int, vnIds)) {
|
||||
// Ciclo sui triangoli del sotto-box corrente
|
||||
for ( auto nT : vnIds) {
|
||||
int nTriaTemp ;
|
||||
int nIdVert[3] ;
|
||||
if ( pStm->GetTempInt( nT, nTriaTemp) && nTriaTemp == 0 && pStm->GetTriangle( nT, nIdVert)) {
|
||||
pStm->SetTempInt( nT, 1) ;
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
Point3d ptVert ;
|
||||
if ( ! pStm->GetVertex( nIdVert[i], ptVert))
|
||||
continue ;
|
||||
double dCurrSqDist = SqDist( ptP, ptVert) ;
|
||||
if ( dCurrSqDist < dMinSqDist) {
|
||||
dMinSqDist = dCurrSqDist ;
|
||||
nVert = nIdVert[i] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Se si verifica la condizione di terminazione arresto il ciclo altrimenti aggiorno i box
|
||||
if ( ! bCollide || dMinSqDist < EPS_SMALL * EPS_SMALL)
|
||||
bContinue = false ;
|
||||
else {
|
||||
boxPPrev = boxP ;
|
||||
boxP.Expand( dDeltaLen) ;
|
||||
}
|
||||
}
|
||||
|
||||
return nVert ;
|
||||
}
|
||||
|
||||
@@ -20,4 +20,5 @@
|
||||
int GetEGkDebugLev( void) ;
|
||||
ILogger* GetEGkLogger( void) ;
|
||||
const std::string& GetEGkKey( void) ;
|
||||
bool GetEGkNetHwKey( void) ;
|
||||
int ProcessEvents( int nProg, int nPause) ;
|
||||
|
||||
+16
-1
@@ -16,7 +16,7 @@
|
||||
#include "DllMain.h"
|
||||
#include "FontManager.h"
|
||||
#include "\EgtDev\Include\EGkDllMain.h"
|
||||
#include "\EgtDev\Include\EgnGetModuleVer.h"
|
||||
#include "\EgtDev\Include\EGnGetModuleVer.h"
|
||||
#include "\EgtDev\Include\EgtTrace.h"
|
||||
#include "\EgtDev\Include\SELkLockId.h"
|
||||
|
||||
@@ -115,6 +115,7 @@ GetEGkLogger( void)
|
||||
//-----------------------------------------------------------------------------
|
||||
static string s_sKey ;
|
||||
static int s_nKeyType = KEY_LOCK_TYPE_ANY ;
|
||||
static bool s_bNetHwKey = false ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
@@ -130,6 +131,13 @@ SetEGkKeyType( int nType)
|
||||
s_nKeyType = nType ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
SetEGkNetHwKey( bool bNetHwKey)
|
||||
{
|
||||
s_bNetHwKey = bNetHwKey ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const string&
|
||||
GetEGkKey( void)
|
||||
@@ -138,6 +146,13 @@ GetEGkKey( void)
|
||||
return s_sKey ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool
|
||||
GetEGkNetHwKey( void)
|
||||
{
|
||||
return s_bNetHwKey ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
InitFontManager( const string& sNfeFontDir, const string& sDefaultFont)
|
||||
|
||||
Binary file not shown.
+38
-19
@@ -22,7 +22,7 @@
|
||||
<ProjectGuid>{9A98A202-2853-454A-84CA-DCD1714176C9}</ProjectGuid>
|
||||
<RootNamespace>EgtGeomKernel</RootNamespace>
|
||||
<Keyword>MFCDLLProj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -30,7 +30,7 @@
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
<PlatformToolset>v141_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
@@ -46,12 +46,12 @@
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
<PlatformToolset>v141_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<PlatformToolset>ClangCL</PlatformToolset>
|
||||
@@ -86,6 +86,7 @@
|
||||
<OutDir>$(SolutionDir)$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||
<IntDir>$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||
<IncludePath>C:\;$(IncludePath)</IncludePath>
|
||||
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<TargetName>$(ProjectName)R$(PlatformArchitecture)</TargetName>
|
||||
@@ -101,6 +102,7 @@
|
||||
<OutDir>$(SolutionDir)$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||
<IntDir>$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||
<IncludePath>C:\;$(IncludePath)</IncludePath>
|
||||
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -114,6 +116,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -149,6 +152,7 @@ copy $(TargetPath) \EgtProg\DllD32</Command>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -195,6 +199,7 @@ copy $(TargetPath) \EgtProg\DllD64</Command>
|
||||
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -237,10 +242,12 @@ copy $(TargetPath) \EgtProg\Dll32</Command>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
||||
<IntelJCCErratum>true</IntelJCCErratum>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -278,6 +285,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="CAvToolTriangle.cpp" />
|
||||
<ClCompile Include="CDeBoxClosedSurfTm.cpp" />
|
||||
<ClCompile Include="CDeBoxTria.cpp" />
|
||||
<ClCompile Include="CDeCapsTria.cpp" />
|
||||
<ClCompile Include="CDeClosedSurfTmClosedSurfTm.cpp" />
|
||||
<ClCompile Include="CDeConeFrustumClosedSurfTm.cpp" />
|
||||
<ClCompile Include="CDeConeFrustumTria.cpp" />
|
||||
@@ -293,6 +301,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="CDeTriaTria.cpp" />
|
||||
<ClCompile Include="CDeUtility.cpp" />
|
||||
<ClCompile Include="ChainCurves.cpp" />
|
||||
<ClCompile Include="Circle2P.cpp" />
|
||||
<ClCompile Include="CircleCenTgCurve.cpp" />
|
||||
<ClCompile Include="Color.cpp" />
|
||||
<ClCompile Include="CreateCurveAux.cpp" />
|
||||
@@ -306,6 +315,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="..\Include\EGkIntersLineBox.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
|
||||
<ClInclude Include="CDeBoxTria.h" />
|
||||
<ClInclude Include="CDeCapsTria.h" />
|
||||
<ClInclude Include="CDeConeFrustumTria.h" />
|
||||
<ClInclude Include="CDeConeTria.h" />
|
||||
<ClInclude Include="CDeConvexTorusTria.h" />
|
||||
@@ -319,7 +329,11 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="DistPointSurfTm.cpp" />
|
||||
<ClCompile Include="DistPointTria.cpp" />
|
||||
<ClCompile Include="ExtDimension.cpp" />
|
||||
<ClCompile Include="HashGrids1d.cpp" />
|
||||
<ClCompile Include="IntersLineBox.cpp" />
|
||||
<ClCompile Include="IntersLineCaps.cpp" />
|
||||
<ClCompile Include="IntersLineCone.cpp" />
|
||||
<ClCompile Include="IntersLineCyl.cpp" />
|
||||
<ClCompile Include="IntersLineSphere.cpp" />
|
||||
<ClCompile Include="IntersLineSurfStd.cpp" />
|
||||
<ClCompile Include="IntersPlaneBox.cpp" />
|
||||
@@ -328,6 +342,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="IntersPlaneTria.cpp" />
|
||||
<ClCompile Include="IntersSurfTmSurfTm.cpp" />
|
||||
<ClCompile Include="IntersTriaTria.cpp" />
|
||||
<ClCompile Include="MedialAxis.cpp" />
|
||||
<ClCompile Include="OffsetCurve.cpp" />
|
||||
<ClCompile Include="DistPointArc.cpp" />
|
||||
<ClCompile Include="DistPointCrvAux.cpp" />
|
||||
@@ -364,12 +379,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="IntersCurveCurve.cpp" />
|
||||
<ClCompile Include="IntersLineArc.cpp" />
|
||||
<ClCompile Include="IntersLineLine.cpp" />
|
||||
<ClCompile Include="IntersLinePlane.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersLinePlane.cpp" />
|
||||
<ClCompile Include="IntersLineSurfTm.cpp" />
|
||||
<ClCompile Include="IntersLineTria.cpp" />
|
||||
<ClCompile Include="Intervals.cpp" />
|
||||
@@ -387,14 +397,17 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="OffsetCurveOnX.cpp" />
|
||||
<ClCompile Include="Polygon3d.cpp" />
|
||||
<ClCompile Include="AdjustLoops.cpp" />
|
||||
<ClCompile Include="RemoveCurveSpikes.cpp" />
|
||||
<ClCompile Include="RemoveCurveDefects.cpp" />
|
||||
<ClCompile Include="SelfIntersCurve.cpp" />
|
||||
<ClCompile Include="SfrCreate.cpp" />
|
||||
<ClCompile Include="SurfAux.cpp" />
|
||||
<ClCompile Include="SurfBezier.cpp" />
|
||||
<ClCompile Include="SurfFlatRegion.cpp" />
|
||||
<ClCompile Include="SurfFlatRegionBooleans.cpp" />
|
||||
<ClCompile Include="SurfFlatRegionOffset.cpp" />
|
||||
<ClCompile Include="SurfTriMeshBooleans.cpp" />
|
||||
<ClCompile Include="SurfTriMeshCuts.cpp" />
|
||||
<ClCompile Include="SurfTriMeshUtilities.cpp" />
|
||||
<ClCompile Include="TextureData.cpp" />
|
||||
<ClCompile Include="Tool.cpp" />
|
||||
<ClCompile Include="UserObjDefault.cpp" />
|
||||
@@ -443,14 +456,14 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="..\Include\EGkChainCurves.h" />
|
||||
<ClInclude Include="..\Include\EGkCircleCenTgCurve.h" />
|
||||
<ClInclude Include="..\Include\EGkColor.h" />
|
||||
<ClInclude Include="..\Include\EgkCurve.h" />
|
||||
<ClInclude Include="..\Include\EgkCurveArc.h" />
|
||||
<ClInclude Include="..\Include\EgkCurveAux.h" />
|
||||
<ClInclude Include="..\Include\EgkCurveBezier.h" />
|
||||
<ClInclude Include="..\Include\EGkCurve.h" />
|
||||
<ClInclude Include="..\Include\EGkCurveArc.h" />
|
||||
<ClInclude Include="..\Include\EGkCurveAux.h" />
|
||||
<ClInclude Include="..\Include\EGkCurveBezier.h" />
|
||||
<ClInclude Include="..\Include\EGkCurveByApprox.h" />
|
||||
<ClInclude Include="..\Include\EgkCurveComposite.h" />
|
||||
<ClInclude Include="..\Include\EGkCurveComposite.h" />
|
||||
<ClInclude Include="..\Include\EGkCurveByInterp.h" />
|
||||
<ClInclude Include="..\Include\EgkCurveLine.h" />
|
||||
<ClInclude Include="..\Include\EGkCurveLine.h" />
|
||||
<ClInclude Include="..\Include\EGkCurveLocal.h" />
|
||||
<ClInclude Include="..\Include\EGkCurvePointDiffGeom.h" />
|
||||
<ClInclude Include="..\Include\EGkDistPointCurve.h" />
|
||||
@@ -560,6 +573,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="DistPointCrvComposite.h" />
|
||||
<ClInclude Include="DistPointLine.h" />
|
||||
<ClInclude Include="DllMain.h" />
|
||||
<ClInclude Include="earcut.hpp" />
|
||||
<ClInclude Include="ExtDimension.h" />
|
||||
<ClInclude Include="ExtText.h" />
|
||||
<ClInclude Include="FontAux.h" />
|
||||
@@ -588,6 +602,10 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="IntersArcArc.h" />
|
||||
<ClInclude Include="IntersCrvCompoCrvCompo.h" />
|
||||
<ClInclude Include="IntersLineArc.h" />
|
||||
<ClInclude Include="IntersLineBox.h" />
|
||||
<ClInclude Include="IntersLineCaps.h" />
|
||||
<ClInclude Include="IntersLineCone.h" />
|
||||
<ClInclude Include="IntersLineCyl.h" />
|
||||
<ClInclude Include="IntersLineLine.h" />
|
||||
<ClInclude Include="IntersLineSurfStd.h" />
|
||||
<ClInclude Include="IntersLineTria.h" />
|
||||
@@ -601,7 +619,8 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="ObjGraphicsMgr.h" />
|
||||
<ClInclude Include="FontOs.h" />
|
||||
<ClInclude Include="AdjustLoops.h" />
|
||||
<ClInclude Include="RemoveCurveSpikes.h" />
|
||||
<ClInclude Include="RemoveCurveDefects.h" />
|
||||
<ClInclude Include="SurfAux.h" />
|
||||
<ClInclude Include="SurfBezier.h" />
|
||||
<ClInclude Include="SurfFlatRegion.h" />
|
||||
<ClInclude Include="TextureData.h" />
|
||||
|
||||
@@ -327,7 +327,7 @@
|
||||
<ClCompile Include="OffsetCurveOnX.cpp">
|
||||
<Filter>File di origine\GeoOffset</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RemoveCurveSpikes.cpp">
|
||||
<ClCompile Include="RemoveCurveDefects.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Polygon3d.cpp">
|
||||
@@ -453,6 +453,36 @@
|
||||
<ClCompile Include="CDeRectPrismoidTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SurfTriMeshUtilities.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SurfTriMeshCuts.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HashGrids1d.cpp">
|
||||
<Filter>File di origine\Base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeCapsTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Circle2P.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MedialAxis.cpp">
|
||||
<Filter>File di origine\GeoOffset</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersLineCyl.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersLineCone.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersLineCaps.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SurfAux.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -623,28 +653,28 @@
|
||||
<ClInclude Include="..\Include\EGkChainCurves.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EgkCurveBezier.h">
|
||||
<ClInclude Include="..\Include\EGkCurveBezier.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkColor.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EgkCurve.h">
|
||||
<ClInclude Include="..\Include\EGkCurve.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EgkCurveArc.h">
|
||||
<ClInclude Include="..\Include\EGkCurveArc.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EgkCurveAux.h">
|
||||
<ClInclude Include="..\Include\EGkCurveAux.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkCurveByInterp.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EgkCurveComposite.h">
|
||||
<ClInclude Include="..\Include\EGkCurveComposite.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EgkCurveLine.h">
|
||||
<ClInclude Include="..\Include\EGkCurveLine.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkCurvePointDiffGeom.h">
|
||||
@@ -839,7 +869,7 @@
|
||||
<ClInclude Include="..\Include\EGkIntersLineSurfTm.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RemoveCurveSpikes.h">
|
||||
<ClInclude Include="RemoveCurveDefects.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkIntersPlanePlane.h">
|
||||
@@ -1076,6 +1106,27 @@
|
||||
<ClInclude Include="CDeRectPrismoidTria.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="earcut.hpp">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntersLineBox.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CDeCapsTria.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntersLineCyl.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntersLineCone.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntersLineCaps.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SurfAux.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+685
-104
File diff suppressed because it is too large
Load Diff
+30
-5
@@ -50,10 +50,11 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // IExtDimension
|
||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||
@@ -61,6 +62,12 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
int nDecDigit, const std::string& sFont, double dTextHeight) override ;
|
||||
bool SetLinear( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptPos,
|
||||
const Vector3d& vtN, const Vector3d& vtDir, const std::string& sText) override ;
|
||||
bool SetRadial( const Point3d& ptCen, const Point3d& ptPos,
|
||||
const Vector3d& vtN, const std::string& sText) override ;
|
||||
bool SetDiametral( const Point3d& ptCen, const Point3d& ptPos,
|
||||
const Vector3d& vtN, const std::string& sText) override ;
|
||||
bool SetAngular( const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptV, const Point3d& ptPos,
|
||||
const Vector3d& vtN, const std::string& sText) override ;
|
||||
const Vector3d& GetNormVersor( void) const override
|
||||
{ return m_vtN ; }
|
||||
const Vector3d& GetDirVersor( void) const override
|
||||
@@ -118,6 +125,7 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
bool GetArrowHead( const Point3d& ptTip, const Vector3d& vtDir, PolyLine& PL) const ;
|
||||
bool SetCurrFont( FontManager& fntMgr) const ;
|
||||
bool ApproxTextWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const ;
|
||||
bool GetTextMyBBox( BBox3d& b3Loc) const ;
|
||||
bool GetTextMyBBox( const Point3d& ptPos, BBox3d& b3Loc) const ;
|
||||
bool GetTextLocalBBox( BBox3d& b3Loc) const ;
|
||||
bool GetTextBBox( const Frame3d& frRef, BBox3d& b3Ref) const ;
|
||||
@@ -139,6 +147,7 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
mutable std::string m_sCalcText ; // testo effettivo della quota
|
||||
mutable Point3d m_ptCalcPos ; // posizione effettiva della quota
|
||||
mutable bool m_bCalcArrowIn ; // flag posizione effettiva delle frecce
|
||||
mutable bool m_bCalcTextOn ; // flag posizione del testo sulla linea di misura
|
||||
mutable Point3d m_ptCalcP7 ; // settimo punto effettivo
|
||||
mutable Point3d m_ptCalcP8 ; // ottavo punto effettivo
|
||||
double m_dExtLineLen ; // lunghezza di estensione della linea
|
||||
@@ -148,5 +157,21 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
int m_nDecDigit ; // numero di cifre decimali
|
||||
std::string m_sFont ; // font del testo
|
||||
double m_dTextHeight ; // altezza del testo
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline ExtDimension* CreateBasicExtDimension( void)
|
||||
{ return ( static_cast<ExtDimension*>( CreateGeoObj( EXT_DIMENSION))) ; }
|
||||
inline ExtDimension* CloneBasicExtDimension( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_DIMENSION)
|
||||
return nullptr ;
|
||||
return ( static_cast<ExtDimension*>( pGObj->Clone())) ; }
|
||||
inline const ExtDimension* GetBasicExtDimension( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_DIMENSION)
|
||||
return nullptr ;
|
||||
return ( static_cast<const ExtDimension*>( pGObj)) ; }
|
||||
inline ExtDimension* GetBasicExtDimension( IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_DIMENSION)
|
||||
return nullptr ;
|
||||
return ( static_cast<ExtDimension*>( pGObj)) ; }
|
||||
|
||||
+37
-3
@@ -35,8 +35,10 @@ GEOOBJ_REGISTER( EXT_TEXT, NGE_E_TXT, ExtText) ;
|
||||
//----------------------------------------------------------------------------
|
||||
ExtText::ExtText( void)
|
||||
: m_pSTM( nullptr), m_bNoSTM( false), m_ptP(), m_vtN( 0, 0, 1), m_vtD( 1, 0, 0), m_sFont(),
|
||||
m_nWeight( 400), m_bItalic( false), m_dHeight( 10), m_dRatio( 1), m_dAddAdvance( 0), m_nTempProp()
|
||||
m_nWeight( 400), m_bItalic( false), m_dHeight( 10), m_dRatio( 1), m_dAddAdvance( 0)
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -159,7 +161,7 @@ ExtText::Clone( void) const
|
||||
bool
|
||||
ExtText::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const ExtText* pTxt = dynamic_cast<const ExtText*>( pGObjSrc) ;
|
||||
const ExtText* pTxt = GetBasicExtText( pGObjSrc) ;
|
||||
if ( pTxt == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pTxt) ;
|
||||
@@ -184,7 +186,8 @@ ExtText::CopyFrom( const ExtText& clSrc)
|
||||
m_dRatio = clSrc.m_dRatio ;
|
||||
m_dAddAdvance = clSrc.m_dAddAdvance ;
|
||||
m_nInsPos = clSrc.m_nInsPos ;
|
||||
m_nTempProp = clSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = clSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = clSrc.m_nTempProp[1] ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -396,8 +399,11 @@ ExtText::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
bool
|
||||
ExtText::Translate( const Vector3d& vtMove)
|
||||
{
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// eseguo
|
||||
m_ptP.Translate( vtMove) ;
|
||||
return true ;
|
||||
}
|
||||
@@ -406,8 +412,15 @@ ExtText::Translate( const Vector3d& vtMove)
|
||||
bool
|
||||
ExtText::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
|
||||
{
|
||||
// verifico validità dell'asse di rotazione
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// eseguo
|
||||
return ( m_ptP.Rotate( ptAx, vtAx, dCosAng, dSinAng) &&
|
||||
m_vtN.Rotate( vtAx, dCosAng, dSinAng) &&
|
||||
m_vtD.Rotate( vtAx, dCosAng, dSinAng)) ;
|
||||
@@ -529,9 +542,18 @@ ExtText::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtD
|
||||
bool
|
||||
ExtText::ToGlob( const Frame3d& frRef)
|
||||
{
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// trasformo punto e versori
|
||||
return ( m_ptP.ToGlob( frRef) &&
|
||||
m_vtN.ToGlob( frRef) &&
|
||||
@@ -542,9 +564,18 @@ ExtText::ToGlob( const Frame3d& frRef)
|
||||
bool
|
||||
ExtText::ToLoc( const Frame3d& frRef)
|
||||
{
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// trasformo punto e versori
|
||||
return ( m_ptP.ToLoc( frRef) &&
|
||||
m_vtN.ToLoc( frRef) &&
|
||||
@@ -558,12 +589,15 @@ ExtText::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
// trasformo punto e versori
|
||||
return ( m_ptP.ToGlob( frOri) && m_ptP.ToLoc( frDest) &&
|
||||
m_vtN.ToGlob( frOri) && m_vtN.ToLoc( frDest) &&
|
||||
|
||||
@@ -50,10 +50,11 @@ class ExtText : public IExtText, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // IExtText
|
||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||
@@ -143,5 +144,21 @@ class ExtText : public IExtText, public IGeoObjRW
|
||||
double m_dRatio ; // rapporto tra larghezza e altezza
|
||||
double m_dAddAdvance ; // avanzamento addizionale tra caratteri
|
||||
int m_nInsPos ; // posizione del punto di inserimento rispetto al testo
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline ExtText* CreateBasicExtText( void)
|
||||
{ return ( static_cast<ExtText*>( CreateGeoObj( EXT_TEXT))) ; }
|
||||
inline ExtText* CloneBasicExtText( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_TEXT)
|
||||
return nullptr ;
|
||||
return ( static_cast<ExtText*>( pGObj->Clone())) ; }
|
||||
inline const ExtText* GetBasicExtText( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_TEXT)
|
||||
return nullptr ;
|
||||
return ( static_cast<const ExtText*>( pGObj)) ; }
|
||||
inline ExtText* GetBasicExtText( IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != EXT_TEXT)
|
||||
return nullptr ;
|
||||
return ( static_cast<ExtText*>( pGObj)) ; }
|
||||
|
||||
+107
-71
@@ -15,13 +15,90 @@
|
||||
#include "stdafx.h"
|
||||
#include "CurveArc.h"
|
||||
#include "CurveLine.h"
|
||||
#include "/EgtDev/Include/EgkFilletChamfer.h"
|
||||
#include "/EgtDev/Include/EgkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkFilletChamfer.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
CalcForFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
const ICurve& cCrv2, const Point3d& ptNear2,
|
||||
const Vector3d& vtNorm, double dRadius,
|
||||
Point3d& ptCen, Point3d& ptTg1, Point3d& ptTg2,
|
||||
int& nSide1, int& nSide2, double& dSinA, double& dTgPar1, double& dTgPar2)
|
||||
{
|
||||
// calcolo un riferimento sul piano perpendicolare alla normale
|
||||
Frame3d frIntr ;
|
||||
if ( ! frIntr.Set( ORIG, vtNorm))
|
||||
return false ;
|
||||
|
||||
// determino il lato di offset della curva 1
|
||||
DistPointCurve dPC1( ptNear2, cCrv1) ;
|
||||
if ( ! dPC1.GetSideAtMinDistPoint( 0, vtNorm, nSide1))
|
||||
return false ;
|
||||
double dOffs1 = ( nSide1 == MDS_RIGHT ? dRadius : - dRadius) ;
|
||||
// calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 1
|
||||
PtrOwner<ICurve> pCopy1( cCrv1.Clone()) ;
|
||||
if ( IsNull( pCopy1))
|
||||
return false ;
|
||||
pCopy1->ToLoc( frIntr) ;
|
||||
pCopy1->SetExtrusion( Z_AX) ;
|
||||
if ( ! pCopy1->SimpleOffset( dOffs1, ICurve::OFF_FILLET))
|
||||
return false ;
|
||||
|
||||
// determino il lato di offset della curva 2
|
||||
DistPointCurve dPC2( ptNear1, cCrv2) ;
|
||||
if ( ! dPC2.GetSideAtMinDistPoint( 0, vtNorm, nSide2))
|
||||
return false ;
|
||||
double dOffs2 = ( nSide2 == MDS_RIGHT ? dRadius : - dRadius) ;
|
||||
// calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 2
|
||||
PtrOwner<ICurve> pCopy2( cCrv2.Clone()) ;
|
||||
if ( IsNull( pCopy2))
|
||||
return false ;
|
||||
pCopy2->ToLoc( frIntr) ;
|
||||
pCopy2->SetExtrusion( Z_AX) ;
|
||||
if ( ! pCopy2->SimpleOffset( dOffs2, ICurve::OFF_FILLET))
|
||||
return false ;
|
||||
|
||||
// calcolo l'intersezione tra le due curve
|
||||
Point3d ptInt1, ptInt2 ;
|
||||
Point3d ptNearI = Media( ptNear1, ptNear2) ;
|
||||
ptNearI.ToLoc( frIntr) ;
|
||||
IntersCurveCurve intCC( *pCopy1, *pCopy2) ;
|
||||
if ( ! intCC.GetIntersPointNearTo( 0, ptNearI, ptInt1) ||
|
||||
! intCC.GetIntersPointNearTo( 1, ptNearI, ptInt2))
|
||||
return false ;
|
||||
ptInt1.ToGlob( frIntr) ;
|
||||
ptInt2.ToGlob( frIntr) ;
|
||||
ptCen = Media( ptInt1, ptInt2) ;
|
||||
|
||||
// proiezione del punto di intersezione sulla prima curva
|
||||
DistPointCurve dPCI1( ptInt1, cCrv1) ;
|
||||
int nFlag1 ;
|
||||
if ( ! dPCI1.GetParamAtMinDistPoint( 0, dTgPar1, nFlag1) || nFlag1 != MDPCI_NORMAL)
|
||||
return false ;
|
||||
Vector3d vtTg1 ;
|
||||
if ( ! cCrv1.GetPointTang( dTgPar1, ICurve::FROM_MINUS, ptTg1, vtTg1))
|
||||
return false ;
|
||||
|
||||
// proiezione del punto di intersezione sulla seconda curva
|
||||
DistPointCurve dPCI2( ptInt2, cCrv2) ;
|
||||
int nFlag2 ;
|
||||
if ( ! dPCI2.GetParamAtMinDistPoint( 0, dTgPar2, nFlag2) || nFlag2 != MDPCI_NORMAL)
|
||||
return false ;
|
||||
Vector3d vtTg2 ;
|
||||
if ( ! cCrv2.GetPointTang( dTgPar2, ICurve::FROM_MINUS, ptTg2, vtTg2))
|
||||
return false ;
|
||||
|
||||
// determino rotazione tra le curve
|
||||
dSinA = ( vtTg1 ^ vtTg2) * vtNorm ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurveArc*
|
||||
CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
@@ -34,76 +111,26 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
&vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr)
|
||||
return nullptr ;
|
||||
|
||||
// calcolo un riferimento sul piano perpendicolare alla normale
|
||||
Frame3d frIntr ;
|
||||
if ( ! frIntr.Set( ORIG, vtNorm))
|
||||
// eseguo calcoli
|
||||
Point3d ptCen, ptTg1, ptTg2 ;
|
||||
int nSide1, nSide2 ;
|
||||
double dSinA, dTgPar1, dTgPar2 ;
|
||||
if ( ! CalcForFillet( cCrv1, ptNear1, cCrv2, ptNear2, vtNorm, dRadius,
|
||||
ptCen, ptTg1, ptTg2, nSide1, nSide2, dSinA, dTgPar1, dTgPar2))
|
||||
return nullptr ;
|
||||
|
||||
// determino il lato di offset della curva 1
|
||||
DistPointCurve dPC1( ptNear2, cCrv1) ;
|
||||
int nSide1 ;
|
||||
if ( ! dPC1.GetSideAtMinDistPoint( 0, vtNorm, nSide1))
|
||||
return nullptr ;
|
||||
double dOffs1 = ( nSide1 == MDS_RIGHT ? dRadius : - dRadius) ;
|
||||
// calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 1
|
||||
PtrOwner<ICurve> pCopy1( cCrv1.Clone()) ;
|
||||
if ( IsNull( pCopy1))
|
||||
return nullptr ;
|
||||
pCopy1->ToLoc( frIntr) ;
|
||||
pCopy1->SetExtrusion( Z_AX) ;
|
||||
if ( ! pCopy1->SimpleOffset( dOffs1, ICurve::OFF_FILLET))
|
||||
return nullptr ;
|
||||
// se tangenti parallele al contatto con fillet, ricalcolo con raggio più piccolo
|
||||
bool bParallel = ( abs( dSinA) < EPS_SMALL) ;
|
||||
if ( bParallel) {
|
||||
Point3d ptQQQ, ptQQ1, ptQQ2 ;
|
||||
double dQQQ1, dQQQ2 ;
|
||||
if ( ! CalcForFillet( cCrv1, ptNear1, cCrv2, ptNear2, vtNorm, dRadius - 10 * EPS_SMALL,
|
||||
ptQQQ, ptQQ1, ptQQ2, nSide1, nSide2, dSinA, dQQQ1, dQQQ2) || abs( dSinA) < EPS_SMALL)
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
// determino il lato di offset della curva 2
|
||||
DistPointCurve dPC2( ptNear1, cCrv2) ;
|
||||
int nSide2 ;
|
||||
if ( ! dPC2.GetSideAtMinDistPoint( 0, vtNorm, nSide2))
|
||||
return nullptr ;
|
||||
double dOffs2 = ( nSide2 == MDS_RIGHT ? dRadius : - dRadius) ;
|
||||
// calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 2
|
||||
PtrOwner<ICurve> pCopy2( cCrv2.Clone()) ;
|
||||
if ( IsNull( pCopy2))
|
||||
return nullptr ;
|
||||
pCopy2->ToLoc( frIntr) ;
|
||||
pCopy2->SetExtrusion( Z_AX) ;
|
||||
if ( ! pCopy2->SimpleOffset( dOffs2, ICurve::OFF_FILLET))
|
||||
return nullptr ;
|
||||
|
||||
// calcolo l'intersezione tra le due curve
|
||||
Point3d ptInt1, ptInt2 ;
|
||||
Point3d ptNear1I = ptNear1 ;
|
||||
ptNear1I.ToLoc( frIntr) ;
|
||||
IntersCurveCurve intCC( *pCopy1, *pCopy2) ;
|
||||
if ( ! intCC.GetIntersPointNearTo( 0, ptNear1I, ptInt1) ||
|
||||
! intCC.GetIntersPointNearTo( 1, ptNear1I, ptInt2))
|
||||
return nullptr ;
|
||||
ptInt1.ToGlob( frIntr) ;
|
||||
ptInt2.ToGlob( frIntr) ;
|
||||
|
||||
// proiezione del punto di intersezione sulla prima curva
|
||||
DistPointCurve dPCI1( ptInt1, cCrv1) ;
|
||||
double dTgPar1 ;
|
||||
int nFlag1 ;
|
||||
if ( ! dPCI1.GetParamAtMinDistPoint( 0, dTgPar1, nFlag1) || nFlag1 != MDPCI_NORMAL)
|
||||
return nullptr ;
|
||||
Point3d ptTg1 ;
|
||||
Vector3d vtTg1 ;
|
||||
if ( ! cCrv1.GetPointTang( dTgPar1, ICurve::FROM_MINUS, ptTg1, vtTg1))
|
||||
return nullptr ;
|
||||
|
||||
// proiezione del punto di intersezione sulla seconda curva
|
||||
DistPointCurve dPCI2( ptInt2, cCrv2) ;
|
||||
double dTgPar2 ;
|
||||
int nFlag2 ;
|
||||
if ( ! dPCI2.GetParamAtMinDistPoint( 0, dTgPar2, nFlag2) || nFlag2 != MDPCI_NORMAL)
|
||||
return nullptr ;
|
||||
Point3d ptTg2 ;
|
||||
Vector3d vtTg2 ;
|
||||
if ( ! cCrv2.GetPointTang( dTgPar2, ICurve::FROM_MINUS, ptTg2, vtTg2))
|
||||
return nullptr ;
|
||||
|
||||
// determino rotazione tra le curve
|
||||
bool bCCW = (( vtTg1 ^ vtTg2) * vtNorm) > 0 ;
|
||||
// orientamento tra le curve
|
||||
bool bCCW = ( dSinA > 0) ;
|
||||
|
||||
// assegno i valori dei parametri di trim (+ da inizio, - da fine)
|
||||
if ( bCCW) {
|
||||
@@ -118,8 +145,17 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
// creo l'arco di fillet
|
||||
PtrOwner<CurveArc> crvFillet( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( crvFillet) ||
|
||||
! crvFillet->SetC2PN( ptInt1, ptTg1, ptTg2, vtNorm))
|
||||
! crvFillet->SetC2PN( ptCen, ptTg1, ptTg2, vtNorm))
|
||||
return nullptr ;
|
||||
// se direzioni agli estremi praticamente parallele
|
||||
if ( bParallel) {
|
||||
// calcolo il verso dell'arco di fillet
|
||||
bool bFilletCcw = ( ( bCCW && nSide1 == nSide2) || ( ! bCCW && nSide1 != nSide2)) ;
|
||||
// si deve verificare se va usato l'arco esplementare
|
||||
bool bArcCcw = ( crvFillet->GetAngCenter() > 0) ;
|
||||
if ( bFilletCcw != bArcCcw)
|
||||
crvFillet->ToExplementary() ;
|
||||
}
|
||||
return Release(crvFillet) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkVector3d.h"
|
||||
#include "/EgtDev/Include/EGtNumCollection.h"
|
||||
#include "/EgtDev/Include/EgtNumCollection.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double AdjustFontRatio( double dRatio) ;
|
||||
|
||||
+2
-2
@@ -17,9 +17,9 @@
|
||||
#include "/EgtDev/Include/EGkGeomDB.h"
|
||||
#include "/EgtDev/Include/EGkGdbIterator.h"
|
||||
#include "/EgtDev/Include/EGkCurve.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include "/EgtDev/Include/EGnFileUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include "/EgtDev/Include/EgnStringUtils.h"
|
||||
#include "/EgtDev/Include/EgnFileUtils.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
+1
-2
@@ -378,8 +378,7 @@ OsFont::GetRegion( const string& sText, int nInsPos, ISURFFRPLIST& lstSFR) const
|
||||
if ( ! GetCharOutline( vCode[i], dAdvance, lstPC))
|
||||
return false ;
|
||||
// lo trasformo opportunamente
|
||||
ICURVEPLIST::iterator iIter ;
|
||||
for ( iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) {
|
||||
for ( auto iIter = lstPC.begin() ; iIter != lstPC.end() ; ++ iIter) {
|
||||
// inverto i percorsi per avere gli esterni CCW
|
||||
(*iIter)->Invert() ;
|
||||
// la trasformo per avere solo archi e rette
|
||||
|
||||
+6
-3
@@ -224,10 +224,10 @@ Frame3d::Set( const Point3d& ptOrig, double dAngCDeg, double dAngADeg, double dA
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Frame3d::Reset( void)
|
||||
Frame3d::Reset( bool bGlob)
|
||||
{
|
||||
m_nType = TOP ;
|
||||
m_nZType = TOP ;
|
||||
m_nType = ( bGlob ? TOP : ERR) ;
|
||||
m_nZType = ( bGlob ? TOP : ERR) ;
|
||||
m_ptOrig = ORIG ;
|
||||
m_vtVersX = X_AX ;
|
||||
m_vtVersY = Y_AX ;
|
||||
@@ -456,6 +456,9 @@ Frame3d::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
bool
|
||||
Frame3d::Verify( void)
|
||||
{
|
||||
// verifica origine
|
||||
if ( ! m_ptOrig.IsValid())
|
||||
return false ;
|
||||
// verifica della ortogonalità dei versori e del senso destrorso
|
||||
double dOrtXY = m_vtVersX * m_vtVersY ;
|
||||
double dOrtYZ = m_vtVersY * m_vtVersZ ;
|
||||
|
||||
+120
-120
@@ -57,7 +57,7 @@
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Per Id di entità
|
||||
// Per Id di entità
|
||||
static const int ID_NO = -99 ;
|
||||
// Per tipo di costruzione di poligono
|
||||
static const int POLYG_INSCR = 1 ;
|
||||
@@ -189,7 +189,7 @@ GdbExecutor::Execute( const string& sCmd1, const string& sCmd2, const STRVECTOR&
|
||||
LOG_ERROR( GetEGkLogger(), "Error : null GeomDb in GdbExecutor.")
|
||||
return ER_ERR ;
|
||||
}
|
||||
// verifico validità CmdParser
|
||||
// verifico validità CmdParser
|
||||
if ( m_pParser == nullptr) {
|
||||
LOG_ERROR( GetEGkLogger(), "Error : null CmdParser in GdbExecutor.")
|
||||
return ER_ERR ;
|
||||
@@ -218,7 +218,7 @@ GdbExecutor::ExecuteGroup( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 2 o 3 parametri : Id, Id del padre[, Frame]
|
||||
if ( vsParams.size() != 2 && vsParams.size() != 3)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -236,7 +236,7 @@ GdbExecutor::ExecuteGroup( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 3 parametri : Id, Id del padre, Orig
|
||||
if ( vsParams.size() != 3)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -253,7 +253,7 @@ GdbExecutor::ExecuteGroup( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// creo il gruppo
|
||||
int nIdDest = GetIdParam( vsParams[0], true) ;
|
||||
int nIdNew = m_pGDB->AddGroup( nIdDest, GetIdParam( vsParams[1]), frFrame) ;
|
||||
// se IdDest da calcolare, può essere una variabili a cui cambiare il valore
|
||||
// se IdDest da calcolare, può essere una variabili a cui cambiare il valore
|
||||
if ( nIdDest == GDB_ID_NULL)
|
||||
m_pParser->SetVariable( vsParams[0], nIdNew) ;
|
||||
|
||||
@@ -270,7 +270,7 @@ GdbExecutor::ExecutePoint( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 3 parametri : Id, IdParent e punto
|
||||
if ( vsParams.size() != 3)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frPnt ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frPnt))
|
||||
return false ;
|
||||
@@ -289,7 +289,7 @@ GdbExecutor::ExecutePoint( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 4 : Id, IdParent, ptP, vtV
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frPnt ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frPnt))
|
||||
return false ;
|
||||
@@ -351,7 +351,7 @@ GdbExecutor::VectorMake( const STRVECTOR& vsParams)
|
||||
// 3 o 4 parametri : Id, IdParent, Vettore [, ScaleFactor]
|
||||
if ( vsParams.size() != 3 && vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect))
|
||||
return false ;
|
||||
@@ -378,7 +378,7 @@ GdbExecutor::VectorFromSpherical( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, IdParent, dLen, dAngVertDeg, dAngOrizzDeg
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect))
|
||||
return false ;
|
||||
@@ -386,7 +386,7 @@ GdbExecutor::VectorFromSpherical( const STRVECTOR& vsParams)
|
||||
double dLen ;
|
||||
if ( ! GetLengthParam( vsParams[2], dLen))
|
||||
return false ;
|
||||
// recupero l'angolo in verticale (non c'è metodo generale)
|
||||
// recupero l'angolo in verticale (non c'è metodo generale)
|
||||
double dAngVertDeg ;
|
||||
if ( ! FromString( vsParams[3], dAngVertDeg))
|
||||
return false ;
|
||||
@@ -410,7 +410,7 @@ GdbExecutor::VectorCrossProduct( const STRVECTOR& vsParams)
|
||||
// 4 o 5 parametri : Id, IdParent, vtV1, vtV2 [, bNorm]
|
||||
if ( vsParams.size() != 4 && vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect))
|
||||
return false ;
|
||||
@@ -444,7 +444,7 @@ GdbExecutor::VectorDifference( const STRVECTOR& vsParams)
|
||||
// 4 o 5 parametri : Id, IdParent, ptP1, ptP2 [, bNorm]
|
||||
if ( vsParams.size() != 4 && vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect))
|
||||
return false ;
|
||||
@@ -478,7 +478,7 @@ GdbExecutor::VectorBaseVector( const STRVECTOR& vsParams)
|
||||
// 4 o 5 parametri : Id, IdParent, PtBase, Vettore [, ScaleFactor]
|
||||
if ( vsParams.size() != 4 && vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect))
|
||||
return false ;
|
||||
@@ -512,7 +512,7 @@ GdbExecutor::VectorModifyBase( const STRVECTOR& vsParams)
|
||||
return false ;
|
||||
// indice dell'oggetto
|
||||
int nId = GetIdParam( vsParams[0]) ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nId, frVect))
|
||||
return false ;
|
||||
@@ -537,7 +537,7 @@ GdbExecutor::ExecuteFrame( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 3 parametri : Id, ParentId, Frame
|
||||
if ( vsParams.size() != 3)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -557,7 +557,7 @@ GdbExecutor::ExecuteFrame( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, ParentId, ptOrig, ptOnX, ptNearY
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -579,7 +579,7 @@ GdbExecutor::ExecuteFrame( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 4 parametri
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -634,7 +634,7 @@ GdbExecutor::CurveLineMake( const STRVECTOR& vsParams)
|
||||
// 4 parametri : Id, IdParent, ptStart, ptEnd
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -664,7 +664,7 @@ GdbExecutor::CurveLineVersorLength( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, IdParent, ptStart, vtDir, dLen
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -698,7 +698,7 @@ GdbExecutor::CurveLineDirLength( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, IdParent, ptStart, dAngDeg, dLen
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -863,7 +863,7 @@ GdbExecutor::CurveLineMinPointCurve( const STRVECTOR& vsParams)
|
||||
// porto il punto nel riferimento della curva
|
||||
Point3d ptSloc = ptStart ;
|
||||
ptSloc.LocToLoc( frPoint, frCurve) ;
|
||||
// recupero eventuale parametro per discriminare tra più soluzioni
|
||||
// recupero eventuale parametro per discriminare tra più soluzioni
|
||||
double dNearParam ;
|
||||
if ( vsParams.size() < 5 || ! FromString( vsParams[4], dNearParam))
|
||||
dNearParam = 0 ;
|
||||
@@ -962,7 +962,7 @@ GdbExecutor::CurveCircleMake( const STRVECTOR& vsParams)
|
||||
// 5 parametri
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -996,7 +996,7 @@ GdbExecutor::CurveCirclePlaneXY( const STRVECTOR& vsParams)
|
||||
// 4 parametri
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1026,7 +1026,7 @@ GdbExecutor::CurveArcMake( const STRVECTOR& vsParams)
|
||||
// 8 parametri
|
||||
if ( vsParams.size() != 8)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1072,7 +1072,7 @@ GdbExecutor::CurveArcPlaneXY( const STRVECTOR& vsParams)
|
||||
// 7 parametri
|
||||
if ( vsParams.size() != 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1114,7 +1114,7 @@ GdbExecutor::CurveArcCircle3P( const STRVECTOR& vsParams, bool bCirc)
|
||||
// 5 parametri : Id, ParentId, ptP0, ptP1, ptP2
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1148,7 +1148,7 @@ GdbExecutor::CurveArc2PDi( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, ParentId, ptPi, ptPf, dDiri
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1164,7 +1164,7 @@ GdbExecutor::CurveArc2PDi( const STRVECTOR& vsParams)
|
||||
double dDirI ;
|
||||
if ( ! GetDirParam( vsParams[4], frRef, dDirI))
|
||||
return false ;
|
||||
// calcolo l'arco (in casi particolari può essere una retta)
|
||||
// calcolo l'arco (in casi particolari può essere una retta)
|
||||
ICurve* pCurve = GetArc2PD( ptPi, ptPf, dDirI) ;
|
||||
if ( pCurve == nullptr)
|
||||
return false ;
|
||||
@@ -1179,7 +1179,7 @@ GdbExecutor::CurveArc2PRS( const STRVECTOR& vsParams)
|
||||
// 5 o 6 parametri : Id, ParentId, ptPi, ptPf, dRad[, CCW/CW]
|
||||
if ( vsParams.size() != 5 && vsParams.size() != 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1217,7 +1217,7 @@ GdbExecutor::CurveArcC2P( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, ParentId, ptCen, ptPi, ptNearPf
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1251,7 +1251,7 @@ GdbExecutor::CurveCircleCenterTgArc( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, ParentId, ptCen, IdArc, ptNear
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frDest ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
|
||||
return false ;
|
||||
@@ -1297,7 +1297,7 @@ GdbExecutor::CurveArcCenterTgArcP( const STRVECTOR& vsParams)
|
||||
// 6 parametri : Id, ParentId, ptCen, IdArc, ptNearTg, ptNearEnd
|
||||
if ( vsParams.size() != 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frDest ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
|
||||
return false ;
|
||||
@@ -1349,7 +1349,7 @@ GdbExecutor::CurveArcPDiTgArc( const STRVECTOR& vsParams)
|
||||
// 6 parametri : Id, ParentId, ptStart, dirStart, IdArc, ptNear
|
||||
if ( vsParams.size() != 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frDest ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
|
||||
return false ;
|
||||
@@ -1382,7 +1382,7 @@ GdbExecutor::CurveArcPDiTgArc( const STRVECTOR& vsParams)
|
||||
return false ;
|
||||
Point3d ptNtloc = ptNear ;
|
||||
ptNtloc.LocToLoc( frDest, frTgArc) ;
|
||||
// calcolo l'arco (in casi particolari può essere una linea)
|
||||
// calcolo l'arco (in casi particolari può essere una linea)
|
||||
ICurve* pCurve = GetArcPntDirTgCurve( ptSloc, FromPolar( 1, dDirI), *pTgArc, ptNtloc, Z_AX) ;
|
||||
if ( pCurve == nullptr)
|
||||
return false ;
|
||||
@@ -1521,7 +1521,7 @@ GdbExecutor::ExecuteCurveBez( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// inizializzo la curva di Bezier
|
||||
if ( ! pCrvBez->Init( nDeg, false))
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1547,7 +1547,7 @@ GdbExecutor::ExecuteCurveBez( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// inizializzo la curva di Bezier
|
||||
if ( ! pCrvBez->Init( nDeg, true))
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1949,7 +1949,7 @@ GdbExecutor::CurveCompoFromPolygon( const STRVECTOR& vsParams, int nType)
|
||||
int nNumLati ;
|
||||
if ( ! FromString( vsParams[2], nNumLati))
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1994,7 +1994,7 @@ GdbExecutor::CurveCompoFromBiarc( const STRVECTOR& vsParams)
|
||||
// 6 o 7 parametri : Id, IdParent, ptP1, Dir1, ptP2, Dir2 [, Par]
|
||||
if ( vsParams.size() != 6 && vsParams.size() != 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -2074,7 +2074,7 @@ GdbExecutor::CurveCompoExtractCurve( const STRVECTOR& vsParams, bool bEndOrStart
|
||||
Frame3d frSou ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdCCompo, frSou))
|
||||
return false ;
|
||||
// estraggo la opportuna entità
|
||||
// estraggo la opportuna entità
|
||||
PtrOwner<ICurve> pCrv( pCrvCompo->RemoveFirstOrLastCurve( bEndOrStart)) ;
|
||||
// se 1 solo parametro -> cancellazione
|
||||
if ( vsParams.size() == 1)
|
||||
@@ -2161,7 +2161,7 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
else if ( sCmd2 == "COMP" || sCmd2 == "DOCOMPACTING") {
|
||||
return SurfTriMeshDoCompacting( vsParams) ;
|
||||
}
|
||||
// se unione di due o più superfici per cucitura
|
||||
// se unione di due o più superfici per cucitura
|
||||
else if ( sCmd2 == "SEW" || sCmd2 == "DOSEWING") {
|
||||
return SurfTriMeshDoSewing( vsParams) ;
|
||||
}
|
||||
@@ -2395,7 +2395,7 @@ GdbExecutor::SurfTriMeshByExtrusion( const STRVECTOR& vsParams)
|
||||
CurveLocal CrvLoc( m_pGDB, nCrvId, frDest) ;
|
||||
if ( CrvLoc.Get() == nullptr)
|
||||
return false ;
|
||||
// recupero il vettore di estrusione (già in locale)
|
||||
// recupero il vettore di estrusione (già in locale)
|
||||
Vector3d vtExtr ;
|
||||
if ( ! GetVectorParam( vsParams[3], frDest, vtExtr))
|
||||
return false ;
|
||||
@@ -2471,7 +2471,7 @@ GdbExecutor::SurfTriMeshByScrewing( bool bMove, const STRVECTOR& vsParams)
|
||||
// recupero la tolleranza lineare
|
||||
if ( vsParams.size() == 7)
|
||||
FromString( vsParams[6], dLinTol) ;
|
||||
// non c'é movimento lungo l'asse
|
||||
// non c'é movimento lungo l'asse
|
||||
}
|
||||
// recupero il riferimento del gruppo destinazione
|
||||
Frame3d frDest ;
|
||||
@@ -2642,7 +2642,7 @@ GdbExecutor::SurfTrimeshClonePart( const STRVECTOR& vsParams)
|
||||
// Parametri : IdNew, IdOld, IdParent, nPart
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// Recupero il riferimento in cui è immerso
|
||||
// Recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[2]), frRef))
|
||||
return false ;
|
||||
@@ -2785,7 +2785,7 @@ GdbExecutor::VolZmapCreate( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptO, dLengthX, dLengthY, dLengthZ, dPrec [, bTriDexel]
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -2829,7 +2829,7 @@ GdbExecutor::VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, idCurv, dPrec, dLengthZ [, bTriDexel]
|
||||
if ( vsParams.size() < 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -2867,7 +2867,7 @@ GdbExecutor::VolZmapCreateFromTriMesh( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, idSurf, dPrec, bFlag
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -2900,7 +2900,7 @@ GdbExecutor::VolZmapMilling( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptPs, ptPe, vtVs, vtVe, dLinTol, dAngTolDeg (dLinTol e dAngTol sono per lavo con gen tool), bType
|
||||
if ( vsParams.size() != 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3019,7 +3019,7 @@ bool GdbExecutor::VolZmapDeepnessMeasure( const STRVECTOR& vsParams) {
|
||||
VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nZmapId)) ;
|
||||
if ( pZmap == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso lo Zmap
|
||||
// recupero il riferimento in cui è immerso lo Zmap
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3051,7 +3051,7 @@ GdbExecutor::VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams)
|
||||
VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nZmapId)) ;
|
||||
if ( pZmap == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso lo Zmap
|
||||
// recupero il riferimento in cui è immerso lo Zmap
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3096,7 +3096,7 @@ GdbExecutor::VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams)
|
||||
// VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nZmapId)) ;
|
||||
// if ( pZmap == nullptr)
|
||||
// return false ;
|
||||
// // recupero il riferimento in cui è immerso lo Zmap
|
||||
// // recupero il riferimento in cui è immerso lo Zmap
|
||||
// Frame3d frRef ;
|
||||
// if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
// return false ;
|
||||
@@ -3143,7 +3143,7 @@ GdbExecutor::VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams)
|
||||
// VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nZmapId)) ;
|
||||
// if ( pZmap == nullptr)
|
||||
// return false;
|
||||
// // recupero il riferimento in cui è immerso lo Zmap
|
||||
// // recupero il riferimento in cui è immerso lo Zmap
|
||||
// Frame3d frRef ;
|
||||
// if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
// return false ;
|
||||
@@ -3213,7 +3213,7 @@ GdbExecutor::LineDiscInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptDisc, ptLine, vtDisc, vtLine, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3281,7 +3281,7 @@ GdbExecutor::RayDiscInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptDisc, ptLine, vtDisc, vtLine, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3349,7 +3349,7 @@ GdbExecutor::SegmentDiscInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptDisc, ptLine, vtDisc, vtLine, dRad, dLen
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3421,7 +3421,7 @@ GdbExecutor::LineSphereInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptC, ptP, vtV, dRad
|
||||
if ( vsParams.size() < 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3472,7 +3472,7 @@ GdbExecutor::RaySphereInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptC, ptP, vtV, dRad
|
||||
if ( vsParams.size() < 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3530,7 +3530,7 @@ GdbExecutor::SegmentSphereInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptC, ptP, vtV, dRad, dLen
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3594,7 +3594,7 @@ GdbExecutor::LineSemiSphereInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptC, ptP, vtSphOr, vtV, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3651,7 +3651,7 @@ GdbExecutor::RaySemiSphereInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptC, ptP, vtSphOr, vtV, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3714,7 +3714,7 @@ GdbExecutor::SegmentSemiSphereInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptC, ptP, vtSphOr, vtV, dRad, dLen
|
||||
if ( vsParams.size() < 8)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3783,7 +3783,7 @@ GdbExecutor::LinCompSemiSphereInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptC, ptP, vtSphOr, vtV, dRad, dLen, nLinType
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3854,7 +3854,7 @@ GdbExecutor::LineInfiniteCylinderInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptCyl, ptLine, vtCyl, vtLine, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3923,7 +3923,7 @@ GdbExecutor::RayInfiniteCylinderInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptCyl, ptLine, vtCyl, vtLine, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3992,7 +3992,7 @@ GdbExecutor::SegmentInfiniteCylinderInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptCyl, ptLine, vtCyl, vtLine, dRad, dLen
|
||||
if ( vsParams.size() < 8)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4064,7 +4064,7 @@ GdbExecutor::SegmentCylinderInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptCyl, ptLine, vtCyl, vtLine, dRad, dCylHeigth, dLen
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4140,7 +4140,7 @@ GdbExecutor::SegmentConeInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptVCone, ptLine, vtCone, vtLine, dRad, dCylHeigth, dLen
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4221,7 +4221,7 @@ GdbExecutor::LineTruncateConeInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptMinBase, ptLine, vtCone, vtLine, dMinRad, dMaxRad, dConeHeigth
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4303,7 +4303,7 @@ GdbExecutor::RayTruncateConeInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptMinBase, ptLine, vtCone, vtLine, dMinRad, dMaxRad, dConeHeigth
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4384,7 +4384,7 @@ GdbExecutor::SegmentTruncateConeInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptMinBase, ptLine, vtCone, vtLine, dMinRad, dMaxRad, dConeHeigth
|
||||
if ( vsParams.size() < 10)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4469,7 +4469,7 @@ GdbExecutor::LineTorusInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptTorus, ptLine, vtTorus, vtLine, dMinRad, dMaxRad,
|
||||
if ( vsParams.size() < 8)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4584,7 +4584,7 @@ GdbExecutor::RayTorusInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptTorus, ptLine, vtTorus, vtLine, dMinRad, dMaxRad,
|
||||
if ( vsParams.size() < 8)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4734,7 +4734,7 @@ GdbExecutor::SegmentTorusInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptTorus, ptLine, vtTorus, vtLine, dMinRad, dMaxRad, dSgLen
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4903,7 +4903,7 @@ GdbExecutor::LinCompTorusPartInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptTorus, ptLine, vtTorus, vtLine, dMinRad, dMaxRad, dSgLen, nLinType
|
||||
if ( vsParams.size() < 10)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -5124,7 +5124,7 @@ GdbExecutor::ExecuteDistPointTrimesh( const std::string& sCmd2, const STRVECTOR&
|
||||
// parametri : Id, IdMovedTria, IdParent, ptP, idSurf
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -5228,7 +5228,7 @@ GdbExecutor::TextSimple( const STRVECTOR& vsParams)
|
||||
// parametri : Id, ParentId, Text, Point, AngDeg, H
|
||||
if ( vsParams.size() != 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -5266,7 +5266,7 @@ GdbExecutor::TextComplete( const STRVECTOR& vsParams)
|
||||
// parametri : Id, ParentId, Text, Point, AngDeg, Font, W, Italic, H, Rat, AddAdv, PosIns
|
||||
if ( vsParams.size() != 12)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -5486,7 +5486,7 @@ GdbExecutor::AddGeoObj( const string& sId, const string& sIdParent, IGeoObj* pGe
|
||||
// creo il gruppo
|
||||
int nId = GetIdParam( sId, true) ;
|
||||
int nIdNew = m_pGDB->AddGeoObj( nId, GetIdParam( sIdParent), pGeoObj) ;
|
||||
// se nId da calcolare, può essere una variabile a cui cambiare il valore
|
||||
// se nId da calcolare, può essere una variabile a cui cambiare il valore
|
||||
if ( nId == GDB_ID_NULL)
|
||||
m_pParser->SetVariable( sId, nIdNew) ;
|
||||
|
||||
@@ -5600,9 +5600,9 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
// ci deve essere almeno un parametro
|
||||
if ( vsParams.size() < 1)
|
||||
return false ;
|
||||
// recupero l'indice dell'entità indicata dal primo parametro
|
||||
// recupero l'indice dell'entità indicata dal primo parametro
|
||||
int nIdEnt = GetIdParam( vsParams[0]) ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frEnt ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt))
|
||||
return false ;
|
||||
@@ -5623,7 +5623,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// se entità geometrica
|
||||
// se entità geometrica
|
||||
const IGeoObj* pGObj ;
|
||||
if ( ( pGObj = m_pGDB->GetGeoObj( nIdEnt)) != nullptr) {
|
||||
// se curva
|
||||
@@ -5659,7 +5659,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
return false ;
|
||||
return vtV.LocToLoc( frEnt, frVect) ;
|
||||
}
|
||||
case 'N' : // versore direzione nel punto più vicino a punto dato
|
||||
case 'N' : // versore direzione nel punto più vicino a punto dato
|
||||
{
|
||||
// secondo parametro : punto di riferimento
|
||||
Point3d ptRef ;
|
||||
@@ -5669,7 +5669,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
ICurve::Side nSide = ICurve::FROM_MINUS ;
|
||||
if ( vsParams.size() >= 3 && vsParams[2] == "+")
|
||||
nSide = ICurve::FROM_PLUS ;
|
||||
// calcolo il parametro del punto della curva più vicino al punto di riferimento
|
||||
// calcolo il parametro del punto della curva più vicino al punto di riferimento
|
||||
DistPointCurve dstPC( ptRef, *pCrv) ;
|
||||
int nFlag ;
|
||||
double dU ;
|
||||
@@ -5723,7 +5723,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
// altrimenti nome di vettore già nel DB
|
||||
// altrimenti nome di vettore già nel DB
|
||||
else {
|
||||
int nIdEnt = GetIdParam( sParam) ;
|
||||
const IGeoVector3d* pV ;
|
||||
@@ -5742,7 +5742,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
bool
|
||||
GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d& ptP)
|
||||
{
|
||||
// se insieme di 2 o 3 coordinate (considerate già nel riferimento frPnt)
|
||||
// se insieme di 2 o 3 coordinate (considerate già nel riferimento frPnt)
|
||||
if ( sParam[0] == '(') {
|
||||
// divido in parti
|
||||
STRVECTOR vsParams ;
|
||||
@@ -5766,7 +5766,7 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
// se altrimenti punto predefinito ORIG (considerato già nel riferimento frPnt)
|
||||
// se altrimenti punto predefinito ORIG (considerato già nel riferimento frPnt)
|
||||
else if ( sParam == "ORIG") {
|
||||
ptP = ORIG ;
|
||||
return true ;
|
||||
@@ -5784,9 +5784,9 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
// ci deve essere almeno un parametro
|
||||
if ( vsParams.size() < 1)
|
||||
return false ;
|
||||
// recupero l'indice dell'entità indicata dal primo parametro
|
||||
// recupero l'indice dell'entità indicata dal primo parametro
|
||||
int nIdEnt = GetIdParam( vsParams[0]) ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frEnt ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt))
|
||||
return false ;
|
||||
@@ -5801,7 +5801,7 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// se entità geometrica
|
||||
// se entità geometrica
|
||||
const IGeoObj* pGObj ;
|
||||
if ( ( pGObj = m_pGDB->GetGeoObj( nIdEnt)) != nullptr) {
|
||||
// se curva
|
||||
@@ -5835,13 +5835,13 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
return false ;
|
||||
return ptP.LocToLoc( frEnt, frPnt) ;
|
||||
}
|
||||
case 'N' : // punto più vicino a punto dato
|
||||
case 'N' : // punto più vicino a punto dato
|
||||
{
|
||||
// secondo parametro : punto di riferimento
|
||||
Point3d ptRef ;
|
||||
if ( vsParams.size() < 2 || ! GetPointParam( vsParams[1], frEnt, ptRef))
|
||||
return false ;
|
||||
// calcolo il punto della curva più vicino al punto di riferimento
|
||||
// calcolo il punto della curva più vicino al punto di riferimento
|
||||
DistPointCurve dstPC( ptRef, *pCrv) ;
|
||||
int nFlag ;
|
||||
if ( ! dstPC.GetMinDistPoint( 0, ptP, nFlag))
|
||||
@@ -5859,11 +5859,11 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
const ICurve* pCrv2 = GetCurve( pGObj2) ;
|
||||
if ( pCrv2 == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frEnt2 ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt2, frEnt2))
|
||||
return false ;
|
||||
// se il riferimento è diverso da quello della prima entità, devo trasformarla
|
||||
// se il riferimento è diverso da quello della prima entità, devo trasformarla
|
||||
PtrOwner<ICurve> pcrvTrans( nullptr) ;
|
||||
if ( ! AreSameFrame( frEnt, frEnt2)) {
|
||||
pcrvTrans.Set( pCrv2->Clone()) ;
|
||||
@@ -5876,7 +5876,7 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
Point3d ptRef ;
|
||||
if ( vsParams.size() >= 3 && ! GetPointParam( vsParams[2], frEnt, ptRef))
|
||||
return false ;
|
||||
// calcolo il punto di intersezione sulla prima curva più vicino al punto di riferimento
|
||||
// calcolo il punto di intersezione sulla prima curva più vicino al punto di riferimento
|
||||
IntersCurveCurve intCC( *pCrv, *pCrv2, true) ;
|
||||
if ( ! intCC.GetIntersPointNearTo( 0, ptRef, ptP))
|
||||
return false ;
|
||||
@@ -5938,7 +5938,7 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
// altrimenti nome di punto già nel DB
|
||||
// altrimenti nome di punto già nel DB
|
||||
else {
|
||||
int nIdEnt = GetIdParam( sParam) ;
|
||||
const IGeoPoint3d* pPt ;
|
||||
@@ -6015,7 +6015,7 @@ GdbExecutor::GetPointWParam( const string& sParam, const Frame3d& frPnt, Point3d
|
||||
FromString( vsParams[1], ptP.y) &&
|
||||
FromString( vsParams[2], dW)) ;
|
||||
}
|
||||
// se 2 parti, nome di punto predefinito, punto notevole o già nel DB e un peso
|
||||
// se 2 parti, nome di punto predefinito, punto notevole o già nel DB e un peso
|
||||
else if ( vsParams.size() == 2) {
|
||||
// recupero il punto
|
||||
if ( ! GetPointParam( vsParams[0], frPnt, ptP))
|
||||
@@ -6065,7 +6065,7 @@ GdbExecutor::GetLengthParam( const string& sParam, double& dLen)
|
||||
// ci deve essere almeno un parametro
|
||||
if ( vsParams.size() < 1)
|
||||
return false ;
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
const IGeoObj* pGObj ;
|
||||
if ( ( pGObj = m_pGDB->GetGeoObj( GetIdParam( vsParams[0]))) == nullptr)
|
||||
return false ;
|
||||
@@ -6088,7 +6088,7 @@ GdbExecutor::GetLengthParam( const string& sParam, double& dLen)
|
||||
// ci deve essere almeno un parametro
|
||||
if ( vsParams.size() < 1)
|
||||
return false ;
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
const IGeoObj* pGObj ;
|
||||
if ( ( pGObj = m_pGDB->GetGeoObj( GetIdParam( vsParams[0]))) == nullptr)
|
||||
return false ;
|
||||
@@ -6124,12 +6124,12 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
// ci deve essere almeno un parametro
|
||||
if ( vsParams.size() < 1)
|
||||
return false ;
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
int nIdEnt = GetIdParam( vsParams[0]) ;
|
||||
const IGeoObj* pGObj ;
|
||||
if ( ( pGObj = m_pGDB->GetGeoObj( nIdEnt)) == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frEnt ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt))
|
||||
return false ;
|
||||
@@ -6143,7 +6143,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
if ( ! pCrv->GetStartDir( vtDir) || ! vtDir.LocToLoc( frEnt, frDir))
|
||||
return false ;
|
||||
vtDir.ToSpherical( nullptr, nullptr, &dDir) ;
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
if ( vsParams.size() >= 2) {
|
||||
double dOffsetDeg = 0 ;
|
||||
FromString( vsParams[1], dOffsetDeg) ;
|
||||
@@ -6154,7 +6154,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
if ( ! pCrv->GetEndDir( vtDir) || ! vtDir.LocToLoc( frEnt, frDir))
|
||||
return false ;
|
||||
vtDir.ToSpherical( nullptr, nullptr, &dDir) ;
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
if ( vsParams.size() >= 2) {
|
||||
double dOffsetDeg = 0 ;
|
||||
FromString( vsParams[1], dOffsetDeg) ;
|
||||
@@ -6165,7 +6165,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
if ( ! pCrv->GetMidDir( vtDir) || ! vtDir.LocToLoc( frEnt, frDir))
|
||||
return false ;
|
||||
vtDir.ToSpherical( nullptr, nullptr, &dDir) ;
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
if ( vsParams.size() >= 2) {
|
||||
double dOffsetDeg = 0 ;
|
||||
FromString( vsParams[1], dOffsetDeg) ;
|
||||
@@ -6196,7 +6196,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
case 'N' : // versore direzione nel punto più vicino a punto dato
|
||||
case 'N' : // versore direzione nel punto più vicino a punto dato
|
||||
{
|
||||
// secondo parametro : punto di riferimento
|
||||
Point3d ptRef ;
|
||||
@@ -6206,7 +6206,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
ICurve::Side nSide = ICurve::FROM_MINUS ;
|
||||
if ( vsParams.size() >= 3 && vsParams[2] == "+")
|
||||
nSide = ICurve::FROM_PLUS ;
|
||||
// calcolo il parametro del punto della curva più vicino al punto di riferimento
|
||||
// calcolo il parametro del punto della curva più vicino al punto di riferimento
|
||||
DistPointCurve dstPC( ptRef, *pCrv) ;
|
||||
int nFlag ;
|
||||
double dU ;
|
||||
@@ -6236,7 +6236,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
Vector3d vtDir = pGVect->GetVector() ;
|
||||
vtDir.LocToLoc( frEnt, frDir) ;
|
||||
vtDir.ToSpherical( nullptr, nullptr, &dDir) ;
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
if ( vsParams.size() >= 2) {
|
||||
double dOffsetDeg = 0 ;
|
||||
FromString( vsParams[1], dOffsetDeg) ;
|
||||
@@ -6294,7 +6294,7 @@ GdbExecutor::GetFrameParam( const string& sParam, const Frame3d& frRef, Frame3d&
|
||||
STRVECTOR::iterator Iter ;
|
||||
for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter)
|
||||
Trim( (*Iter), " \t\r\n") ;
|
||||
// se c'è un parametro è l'origine
|
||||
// se c'è un parametro è l'origine
|
||||
Point3d ptOrig ;
|
||||
if ( vsParams.size() >= 1) {
|
||||
if ( ! GetPointParam( vsParams[0], frRef, ptOrig))
|
||||
@@ -6325,11 +6325,11 @@ GdbExecutor::GetFrameParam( const string& sParam, const Frame3d& frRef, Frame3d&
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
// altrimenti nome di gruppo o di frame già nel DB
|
||||
// altrimenti nome di gruppo o di frame già nel DB
|
||||
else {
|
||||
// identificativo
|
||||
int nIdEnt = GetIdParam( sParam) ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frEnt ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt))
|
||||
return false ;
|
||||
@@ -6337,7 +6337,7 @@ GdbExecutor::GetFrameParam( const string& sParam, const Frame3d& frRef, Frame3d&
|
||||
if ( m_pGDB->GetGroupFrame( nIdEnt, frF)) {
|
||||
return frF.LocToLoc( frEnt, frRef) ;
|
||||
}
|
||||
// altrimenti entità geometrica
|
||||
// altrimenti entità geometrica
|
||||
else {
|
||||
// verifico se riferimento
|
||||
const IGeoFrame3d* pFr ;
|
||||
@@ -6393,7 +6393,7 @@ GdbExecutor::GetColorParam( const string& sParam, bool& bByParent, Color& cCol)
|
||||
// ci deve essere un parametro
|
||||
if ( vsParams.size() != 1)
|
||||
return false ;
|
||||
// recupero il colore dell'entità indicata dal parametro
|
||||
// recupero il colore dell'entità indicata dal parametro
|
||||
bByParent = false ;
|
||||
return m_pGDB->GetCalcMaterial( GetIdParam( vsParams[0]), cCol) ;
|
||||
}
|
||||
@@ -6427,7 +6427,7 @@ GdbExecutor::GetMaterialParam( const string& sParam, bool& bByParent, int& nMat)
|
||||
// ci deve essere un parametro
|
||||
if ( vsParams.size() != 1)
|
||||
return false ;
|
||||
// recupero il materiale dell'entità indicata dal parametro
|
||||
// recupero il materiale dell'entità indicata dal parametro
|
||||
bByParent = false ;
|
||||
return ( m_pGDB->GetCalcMaterial( GetIdParam( vsParams[0]), nMat) && nMat != GDB_MT_COLOR) ;
|
||||
}
|
||||
@@ -6975,7 +6975,7 @@ GdbExecutor::ExecuteCopy( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
nIdNew = m_pGDB->CopyGlob( GetIdParam( vsParams[0]), nIdDest, GetIdParam( vsParams[2]), nSonBeforeAfter) ;
|
||||
else
|
||||
nIdNew = m_pGDB->Copy( GetIdParam( vsParams[0]), nIdDest, GetIdParam( vsParams[2]), nSonBeforeAfter) ;
|
||||
// se IdDest da calcolare, può essere una variabile a cui cambiare il valore
|
||||
// se IdDest da calcolare, può essere una variabile a cui cambiare il valore
|
||||
if ( nIdDest == GDB_ID_NULL)
|
||||
m_pParser->SetVariable( vsParams[1], nIdNew) ;
|
||||
|
||||
@@ -7647,7 +7647,7 @@ GdbExecutor::CurveCopyBySplitClass( const STRVECTOR& vsParams)
|
||||
IntersCurveCurve intCC( *pCrv, *pCloCrv, true) ;
|
||||
// recupero la classificazione della prima curva
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ! intCC.GetCurveClassification( 0, ccClass))
|
||||
if ( ! intCC.GetCurveClassification( 0, EPS_SMALL, ccClass))
|
||||
return false ;
|
||||
// recupero gli indici dei gruppi destinazione e i loro riferimenti
|
||||
const int N_GRP = 4 ;
|
||||
@@ -7877,7 +7877,7 @@ GdbExecutor::ExecuteOutTextIcci( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// devono essere 6 parametri : IdText, IdGroup, IdEnt1, IdEnt2, ptText, hText
|
||||
if ( vsParams.size() != 6)
|
||||
return false ;
|
||||
// recupero l'indice delle entità
|
||||
// recupero l'indice delle entità
|
||||
int nIdEnt1 = GetIdParam( vsParams[2]) ;
|
||||
int nIdEnt2 = GetIdParam( vsParams[3]) ;
|
||||
// verifico siano due curve
|
||||
@@ -7894,7 +7894,7 @@ GdbExecutor::ExecuteOutTextIcci( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
Frame3d frEnt2 ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt2, frEnt2))
|
||||
return false ;
|
||||
// se i riferimenti sono diversi, porto la seconda entità nel riferimento della prima
|
||||
// se i riferimenti sono diversi, porto la seconda entità nel riferimento della prima
|
||||
PtrOwner<ICurve> pcrvTrans ;
|
||||
if ( ! AreSameFrame( frEnt1, frEnt2)) {
|
||||
pcrvTrans.Set( pCrv2->Clone()) ;
|
||||
@@ -7921,7 +7921,7 @@ GdbExecutor::ExecuteOutTextIcci( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
sText += "<br/> " ;
|
||||
sText += " U=" + ToString( aInfo.IciA[j].dU,7) + " P=(" + ToString( aInfo.IciA[j].ptI,4) + ")" ;
|
||||
switch( aInfo.IciA[j].nPrevTy) {
|
||||
case ICCT_NULL : sText += " ??-" ; break ;
|
||||
case ICCT_NULL : sText += " ?" "?-" ; break ;
|
||||
case ICCT_IN : sText += " IN-" ; break ;
|
||||
case ICCT_OUT : sText += " OUT-" ; break ;
|
||||
case ICCT_ON : sText += " ON-" ; break ;
|
||||
@@ -7940,7 +7940,7 @@ GdbExecutor::ExecuteOutTextIcci( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
sText += string( "<br/>") + ( aInfo.bCBOverEq ? " + " : " - ") ;
|
||||
sText += " U=" + ToString( aInfo.IciB[j].dU,7) + " P=(" + ToString( aInfo.IciB[j].ptI,4) + ")" ;
|
||||
switch( aInfo.IciB[j].nPrevTy) {
|
||||
case ICCT_NULL : sText += " ??-" ; break ;
|
||||
case ICCT_NULL : sText += " ?" "?-" ; break ;
|
||||
case ICCT_IN : sText += " IN-" ; break ;
|
||||
case ICCT_OUT : sText += " OUT-" ; break ;
|
||||
case ICCT_ON : sText += " ON-" ; break ;
|
||||
@@ -7953,7 +7953,7 @@ GdbExecutor::ExecuteOutTextIcci( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
}
|
||||
}
|
||||
}
|
||||
// recupero il riferimento in cui è immerso il testo
|
||||
// recupero il riferimento in cui è immerso il testo
|
||||
Frame3d frText ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frText))
|
||||
return false ;
|
||||
@@ -8090,7 +8090,7 @@ bool
|
||||
GdbExecutor::OutGroupTsc( int nId, int nFlag, int nLev)
|
||||
{
|
||||
m_OutTsc.Remark( "Start Group ---") ;
|
||||
// emetto dati gruppo ( se non è radice)
|
||||
// emetto dati gruppo ( se non è radice)
|
||||
if ( nId > GDB_ID_ROOT) {
|
||||
Frame3d frFrame ;
|
||||
if ( ( nLev == 0 && m_pGDB->GetGroupGlobFrame( nId, frFrame)) ||
|
||||
@@ -8113,7 +8113,7 @@ GdbExecutor::OutGroupTsc( int nId, int nFlag, int nLev)
|
||||
}
|
||||
}
|
||||
}
|
||||
// emetto entità gruppo
|
||||
// emetto entità gruppo
|
||||
m_OutTsc.Remark( "Entities :") ;
|
||||
GdbIterator Iter( m_pGDB) ;
|
||||
bool bNext = Iter.GoToFirstInGroup( nId) ;
|
||||
|
||||
+2
-2
@@ -14,10 +14,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "OutTsc.h"
|
||||
#include "/EgtDev/Include/EgkGdbExecutor.h"
|
||||
#include "/EgtDev/Include/EGkGdbExecutor.h"
|
||||
#include "/EgtDev/Include/EgtPerfCounter.h"
|
||||
#include "/EgtDev/Include/EgtExecMgr.h"
|
||||
#include "/EgtDev/Include/EgkGeoCollection.h"
|
||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||
#include "Tool.h"
|
||||
|
||||
class PolyLine ;
|
||||
|
||||
@@ -54,6 +54,10 @@ class GdbGeo : public GdbObj
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline const GdbGeo* GetGdbGeo( const GdbObj* pGObj)
|
||||
{ return dynamic_cast<const GdbGeo*>(pGObj) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GEO)
|
||||
return nullptr ;
|
||||
return static_cast<const GdbGeo*>( pGObj) ; }
|
||||
inline GdbGeo* GetGdbGeo( GdbObj* pGObj)
|
||||
{ return dynamic_cast<GdbGeo*>(pGObj) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GEO)
|
||||
return nullptr ;
|
||||
return static_cast<GdbGeo*>( pGObj) ; }
|
||||
|
||||
+6
-2
@@ -91,6 +91,10 @@ class GdbGroup : public GdbObj
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline const GdbGroup* GetGdbGroup( const GdbObj* pGObj)
|
||||
{ return dynamic_cast<const GdbGroup*>(pGObj) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GROUP)
|
||||
return nullptr ;
|
||||
return static_cast<const GdbGroup*>( pGObj) ; }
|
||||
inline GdbGroup* GetGdbGroup( GdbObj* pGObj)
|
||||
{ return dynamic_cast<GdbGroup*>(pGObj) ; }
|
||||
{ if ( pGObj == nullptr || pGObj->GetGdbType() != GDB_TY_GROUP)
|
||||
return nullptr ;
|
||||
return static_cast<GdbGroup*>( pGObj) ; }
|
||||
|
||||
+64
-8
@@ -24,7 +24,7 @@ using namespace std ;
|
||||
IGdbIterator*
|
||||
CreateGdbIterator( IGeomDB* pGDB)
|
||||
{
|
||||
if ( dynamic_cast<GeomDB*>( pGDB) == nullptr)
|
||||
if ( static_cast<GeomDB*>( pGDB) == nullptr)
|
||||
return nullptr ;
|
||||
return static_cast<IGdbIterator*> ( new( nothrow) GdbIterator( pGDB)) ;
|
||||
}
|
||||
@@ -53,7 +53,7 @@ GdbIterator::~GdbIterator( void)
|
||||
bool
|
||||
GdbIterator::SetGDB( IGeomDB* pGDB)
|
||||
{
|
||||
m_pGDB = dynamic_cast<GeomDB*>( pGDB) ;
|
||||
m_pGDB = static_cast<GeomDB*>( pGDB) ;
|
||||
if ( m_pGDB == nullptr)
|
||||
return false ;
|
||||
|
||||
@@ -105,7 +105,7 @@ GdbIterator::GoToFirstInGroup( const IGdbIterator& iIter)
|
||||
return false ;
|
||||
}
|
||||
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -167,7 +167,7 @@ GdbIterator::GoToLastInGroup( const IGdbIterator& iIter)
|
||||
return false ;
|
||||
}
|
||||
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -263,7 +263,7 @@ GdbIterator::GoToFirstNameInGroup( const IGdbIterator& iIter, const string& sNam
|
||||
return false ;
|
||||
}
|
||||
// converto in oggetto iteratore di base
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -345,7 +345,7 @@ GdbIterator::GoToLastNameInGroup( const IGdbIterator& iIter, const string& sName
|
||||
return false ;
|
||||
}
|
||||
// converto in oggetto iteratore di base
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -474,7 +474,7 @@ GdbIterator::GoToFirstGroupInGroup( const IGdbIterator& iIter)
|
||||
return false ;
|
||||
}
|
||||
// converto in oggetto iteratore di base
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -553,7 +553,7 @@ GdbIterator::GoToLastGroupInGroup( const IGdbIterator& iIter)
|
||||
return false ;
|
||||
}
|
||||
// converto in oggetto iteratore di base
|
||||
const GdbIterator* pIter = dynamic_cast<const GdbIterator*> (&iIter) ;
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB) {
|
||||
m_pCurrObj = nullptr ;
|
||||
return false ;
|
||||
@@ -1618,6 +1618,62 @@ GdbIterator::RemoveInfo( const string& sKey)
|
||||
return m_pCurrObj->RemoveInfo( sKey) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbIterator::GetAllInfo( STRVECTOR& vsInfo) const
|
||||
{
|
||||
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
|
||||
return false ;
|
||||
|
||||
// recupero tutte le Info
|
||||
return m_pCurrObj->GetAllInfo( vsInfo) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbIterator::CopyAllInfoFrom( const IGdbIterator& iIter)
|
||||
{
|
||||
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
|
||||
return false ;
|
||||
|
||||
// recupero l'oggetto sorgente
|
||||
const GdbIterator* pIter = static_cast<const GdbIterator*> (&iIter) ;
|
||||
if ( pIter == nullptr || pIter->m_pGDB != m_pGDB || pIter->m_pCurrObj == nullptr)
|
||||
return false ;
|
||||
const GdbObj* pGdbObjSou = pIter->m_pCurrObj ;
|
||||
|
||||
// copio tutte le Info
|
||||
if ( m_pCurrObj != pGdbObjSou && pGdbObjSou->m_pAttribs != nullptr) {
|
||||
m_pCurrObj->GetSafeAttribs() ;
|
||||
return ( m_pCurrObj->m_pAttribs != nullptr && m_pCurrObj->m_pAttribs->CopyAllInfoFrom( *(pGdbObjSou->m_pAttribs))) ;
|
||||
}
|
||||
else
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Stipple (significativo solo per curve)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbIterator::SetStipple( int nFactor, int nPattern)
|
||||
{
|
||||
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
|
||||
return false ;
|
||||
// imposto lo stipple
|
||||
return m_pCurrObj->SetStipple( nFactor, nPattern) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbIterator::GetStipple( int& nFactor, int& nPattern) const
|
||||
{
|
||||
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
|
||||
return false ;
|
||||
// recupero lo stipple
|
||||
return m_pCurrObj->GetStipple( nFactor, nPattern) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// TextureData
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
+7
-2
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2013
|
||||
// EgalTech 2013-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : GdbIterator.h Data : 04.12.13 Versione : 1.4a3
|
||||
// File : GdbIterator.h Data : 09.07.23 Versione : 2.5g1
|
||||
// Contenuto : Dichiarazione della classe GdbIterator.
|
||||
//
|
||||
//
|
||||
@@ -142,6 +142,11 @@ class GdbIterator : public IGdbIterator
|
||||
bool GetInfo( const std::string& sKey, STRVECTOR& vsInfo) const override ;
|
||||
bool ExistsInfo( const std::string& sKey) const override ;
|
||||
bool RemoveInfo( const std::string& sKey) override ;
|
||||
bool GetAllInfo( STRVECTOR& vsInfo) const override ;
|
||||
bool CopyAllInfoFrom( const IGdbIterator& iIter) override ;
|
||||
// Stipple
|
||||
bool SetStipple( int nFactor, int nPattern) override ;
|
||||
bool GetStipple( int& nFactor, int& nPattern) const override ;
|
||||
// TextureData
|
||||
bool SetTextureName( const std::string& sTxrName) override ;
|
||||
bool SetTextureFrame( const Frame3d& frTxrRef) override ;
|
||||
|
||||
+43
-3
@@ -31,9 +31,9 @@ using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
GdbObj::GdbObj( void)
|
||||
: m_nId( GDB_ID_NULL), m_pAttribs( nullptr), m_pTxrData( nullptr), m_pUserObj( nullptr),
|
||||
m_pSelPrev( nullptr), m_pSelNext( nullptr),
|
||||
m_pGDB( nullptr), m_pNext( nullptr), m_pPrev( nullptr), m_pParent( nullptr)
|
||||
: m_nId( GDB_ID_NULL), m_pAttribs( nullptr), m_nStpFactor( 0), m_nStpPattern( 0), m_pTxrData( nullptr),
|
||||
m_pUserObj( nullptr), m_pGDB( nullptr), m_pNext( nullptr), m_pPrev( nullptr), m_pParent( nullptr),
|
||||
m_pSelNext( nullptr), m_pSelPrev( nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -72,6 +72,9 @@ GdbObj::CopyFrom( const GdbObj* pSou)
|
||||
if ( m_pAttribs != nullptr)
|
||||
delete m_pAttribs ;
|
||||
m_pAttribs = nullptr ;
|
||||
// reset stipple
|
||||
m_nStpFactor = 0 ;
|
||||
m_nStpPattern = 0 ;
|
||||
// elimino eventuali dati della texture pre-esistenti
|
||||
if ( m_pTxrData != nullptr)
|
||||
delete m_pTxrData ;
|
||||
@@ -90,6 +93,10 @@ GdbObj::CopyFrom( const GdbObj* pSou)
|
||||
// copio Id
|
||||
m_nId = pSou->m_nId ;
|
||||
|
||||
// copio stipple
|
||||
m_nStpFactor = pSou->m_nStpFactor ;
|
||||
m_nStpPattern = pSou->m_nStpPattern ;
|
||||
|
||||
// copio gli attributi, i dati della texture e UserObj
|
||||
return ( CopyAttribsFrom( pSou) && CopyTextureDataFrom( pSou) && CopyUserObjFrom( pSou)) ;
|
||||
}
|
||||
@@ -1023,6 +1030,39 @@ GdbObj::RemoveInfo( const string& sKey)
|
||||
return m_pAttribs->RemoveInfo( sKey) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbObj::GetAllInfo( STRVECTOR& vsInfo) const
|
||||
{
|
||||
// se non ci sono attributi
|
||||
if ( m_pAttribs == nullptr) {
|
||||
vsInfo.clear() ;
|
||||
return true ;
|
||||
}
|
||||
// recupero tutte le Info
|
||||
return m_pAttribs->GetAllInfo( vsInfo) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Stipple (significativo solo per curve, per ora non viene salvato)
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbObj::SetStipple( int nFactor, int nPattern)
|
||||
{
|
||||
m_nStpFactor = nFactor ;
|
||||
m_nStpPattern = nPattern ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbObj::GetStipple( int& nFactor, int& nPattern) const
|
||||
{
|
||||
nFactor = m_nStpFactor ;
|
||||
nPattern = m_nStpPattern ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// TextureData
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -119,6 +119,9 @@ class GdbObj
|
||||
bool GetInfo( const std::string& sKey, STRVECTOR& vsInfo) const ;
|
||||
bool ExistsInfo( const std::string& sKey) const ;
|
||||
bool RemoveInfo( const std::string& sKey) ;
|
||||
bool GetAllInfo( STRVECTOR& vsInfo) const ;
|
||||
bool SetStipple( int nFactor, int nPattern) ;
|
||||
bool GetStipple( int& nFactor, int& nPattern) const ;
|
||||
bool SaveTextureData( NgeWriter& ngeOut) const ;
|
||||
bool LoadTextureData( NgeReader& ngeIn) ;
|
||||
TextureData* GetTextureData( void)
|
||||
@@ -160,6 +163,8 @@ class GdbObj
|
||||
public :
|
||||
int m_nId ;
|
||||
Attribs* m_pAttribs ;
|
||||
int m_nStpFactor ;
|
||||
int m_nStpPattern ;
|
||||
TextureData* m_pTxrData ;
|
||||
IUserObj* m_pUserObj ;
|
||||
|
||||
|
||||
+6
-2
@@ -50,7 +50,11 @@ const double BEZARC_ANG_CEN_MAX = 90 ;
|
||||
//----------------- Costanti per superfici TriMesh ---------------------------
|
||||
// tolleranza lineare standard
|
||||
const double STM_STD_LIN_TOL = 0.1 ;
|
||||
// angolo limite per definire un edge che è contorno di poligono
|
||||
// angolo limite standard per definire un edge che è contorno di poligono
|
||||
const double STM_STD_BOUNDARY_ANG = 0.1 ;
|
||||
// angolo limite per mediare le normali in un vertice
|
||||
// angolo limite standard per mediare le normali in un vertice
|
||||
const double STM_STD_SMOOTH_ANG = 25.0 ;
|
||||
// distanza limite tra diagonali per quadrilatero con twist
|
||||
const double STM_TWIST_DIAG_DIST = 1.0 ;
|
||||
// angolo limite con twist per mediare le normali in un vertice
|
||||
const double STM_TWIST_SMOOTH_ANG = 35.0 ;
|
||||
|
||||
+6
-3
@@ -29,8 +29,10 @@ GEOOBJ_REGISTER( GEO_FRAME3D, NGE_G_FRM, GeoFrame3d) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
GeoFrame3d::GeoFrame3d( void)
|
||||
: m_frF(), m_nTempProp()
|
||||
: m_frF()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -102,7 +104,7 @@ GeoFrame3d::Clone( void) const
|
||||
bool
|
||||
GeoFrame3d::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const GeoFrame3d* pGFr = dynamic_cast<const GeoFrame3d*>( pGObjSrc) ;
|
||||
const GeoFrame3d* pGFr = GetBasicGeoFrame3d( pGObjSrc) ;
|
||||
if ( pGFr == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pGFr) ;
|
||||
@@ -114,7 +116,8 @@ GeoFrame3d::CopyFrom( const GeoFrame3d& gfSrc)
|
||||
{
|
||||
if ( &gfSrc == this)
|
||||
return true ;
|
||||
m_nTempProp = gfSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = gfSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = gfSrc.m_nTempProp[1] ;
|
||||
return Set( gfSrc.m_frF) ;
|
||||
}
|
||||
|
||||
|
||||
+22
-5
@@ -57,10 +57,11 @@ class GeoFrame3d : public IGeoFrame3d, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // IGeoFrame3d
|
||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||
@@ -95,5 +96,21 @@ class GeoFrame3d : public IGeoFrame3d, public IGeoObjRW
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
Frame3d m_frF ; // oggetto
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline GeoFrame3d* CreateBasicGeoFrame3d( void)
|
||||
{ return ( static_cast<GeoFrame3d*>( CreateGeoObj( GEO_FRAME3D))) ; }
|
||||
inline GeoFrame3d* CloneBasicGeoFrame3d( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_FRAME3D)
|
||||
return nullptr ;
|
||||
return ( static_cast<GeoFrame3d*>( pGObj->Clone())) ; }
|
||||
inline const GeoFrame3d* GetBasicGeoFrame3d( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_FRAME3D)
|
||||
return nullptr ;
|
||||
return ( static_cast<const GeoFrame3d*>( pGObj)) ; }
|
||||
inline GeoFrame3d* GetBasicGeoFrame3d( IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_FRAME3D)
|
||||
return nullptr ;
|
||||
return ( static_cast<GeoFrame3d*>( pGObj)) ; }
|
||||
|
||||
+6
-3
@@ -28,8 +28,10 @@ GEOOBJ_REGISTER( GEO_PNT3D, NGE_G_PNT, GeoPoint3d) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
GeoPoint3d::GeoPoint3d( void)
|
||||
: m_ptP(), m_nTempProp()
|
||||
: m_ptP()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -70,7 +72,7 @@ GeoPoint3d::Clone( void) const
|
||||
bool
|
||||
GeoPoint3d::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const GeoPoint3d* pGP = dynamic_cast<const GeoPoint3d*>( pGObjSrc) ;
|
||||
const GeoPoint3d* pGP = GetBasicGeoPoint3d( pGObjSrc) ;
|
||||
if ( pGP == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pGP) ;
|
||||
@@ -82,7 +84,8 @@ GeoPoint3d::CopyFrom( const GeoPoint3d& clSrc)
|
||||
{
|
||||
if ( &clSrc == this)
|
||||
return true ;
|
||||
m_nTempProp = clSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = clSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = clSrc.m_nTempProp[1] ;
|
||||
return Set( clSrc.m_ptP) ;
|
||||
}
|
||||
|
||||
|
||||
+22
-5
@@ -57,10 +57,11 @@ class GeoPoint3d : public IGeoPoint3d, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // IGeoPoint3d
|
||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||
@@ -89,5 +90,21 @@ class GeoPoint3d : public IGeoPoint3d, public IGeoObjRW
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
Point3d m_ptP ; // oggetto
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline GeoPoint3d* CreateBasicGeoPoint3d( void)
|
||||
{ return ( static_cast<GeoPoint3d*>( CreateGeoObj( GEO_PNT3D))) ; }
|
||||
inline GeoPoint3d* CloneBasicGeoPoint3d( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_PNT3D)
|
||||
return nullptr ;
|
||||
return ( static_cast<GeoPoint3d*>( pGObj->Clone())) ; }
|
||||
inline const GeoPoint3d* GetBasicGeoPoint3d( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_PNT3D)
|
||||
return nullptr ;
|
||||
return ( static_cast<const GeoPoint3d*>( pGObj)) ; }
|
||||
inline GeoPoint3d* GetBasicGeoPoint3d( IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_PNT3D)
|
||||
return nullptr ;
|
||||
return ( static_cast<GeoPoint3d*>( pGObj)) ; }
|
||||
|
||||
+6
-3
@@ -29,8 +29,10 @@ GEOOBJ_REGISTER( GEO_VECT3D, NGE_G_VEC, GeoVector3d) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
GeoVector3d::GeoVector3d( void)
|
||||
: m_vtV(), m_nTempProp()
|
||||
: m_vtV()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -86,7 +88,7 @@ GeoVector3d::Clone( void) const
|
||||
bool
|
||||
GeoVector3d::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
const GeoVector3d* pGV = dynamic_cast<const GeoVector3d*>( pGObjSrc) ;
|
||||
const GeoVector3d* pGV = GetBasicGeoVector3d( pGObjSrc) ;
|
||||
if ( pGV == nullptr)
|
||||
return false ;
|
||||
return CopyFrom( *pGV) ;
|
||||
@@ -98,7 +100,8 @@ GeoVector3d::CopyFrom( const GeoVector3d& clSrc)
|
||||
{
|
||||
if ( &clSrc == this)
|
||||
return true ;
|
||||
m_nTempProp = clSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = clSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = clSrc.m_nTempProp[1] ;
|
||||
return Set( clSrc.m_vtV, clSrc.m_ptBase) ;
|
||||
}
|
||||
|
||||
|
||||
+22
-5
@@ -65,10 +65,11 @@ class GeoVector3d : public IGeoVector3d, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // IGeoVector3d
|
||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||
@@ -104,5 +105,21 @@ class GeoVector3d : public IGeoVector3d, public IGeoObjRW
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
Vector3d m_vtV ; // oggetto
|
||||
Point3d m_ptBase ; // punto base da cui tracciare il vettore
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline GeoVector3d* CreateBasicGeoVector3d( void)
|
||||
{ return ( static_cast<GeoVector3d*>( CreateGeoObj( GEO_VECT3D))) ; }
|
||||
inline GeoVector3d* CloneBasicGeoVector3d( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_VECT3D)
|
||||
return nullptr ;
|
||||
return ( static_cast<GeoVector3d*>( pGObj->Clone())) ; }
|
||||
inline const GeoVector3d* GetBasicGeoVector3d( const IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_VECT3D)
|
||||
return nullptr ;
|
||||
return ( static_cast<const GeoVector3d*>( pGObj)) ; }
|
||||
inline GeoVector3d* GetBasicGeoVector3d( IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != GEO_VECT3D)
|
||||
return nullptr ;
|
||||
return ( static_cast<GeoVector3d*>( pGObj)) ; }
|
||||
|
||||
+167
-28
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2013
|
||||
// EgalTech 2013-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : GeomDB.cpp Data : 08.04.13 Versione : 1.3a5
|
||||
// File : GeomDB.cpp Data : 29.05.23 Versione : 2.5e5
|
||||
// Contenuto : Implementazione della classe GeomDB.
|
||||
//
|
||||
//
|
||||
@@ -21,17 +21,40 @@
|
||||
#include "NgeReader.h"
|
||||
#include "NgeWriter.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/SELkLockId.h"
|
||||
#include "/EgtDev/Include/SELkKeyProc.h"
|
||||
#include "/EgtDev/Include/EGnGetKeyData.h"
|
||||
#include "/EgtDev/Include/EgtStringConverter.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include "/EgtDev/Include/EgtNumCollection.h"
|
||||
#include "/EgtDev/Include/EgtKeyCodes.h"
|
||||
#include "/EgtDev/Include/SELkLockId.h"
|
||||
#include "/EgtDev/Include/SELkKeyProc.h"
|
||||
#include <new>
|
||||
#include <stack>
|
||||
#include <thread>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class LockAddErase
|
||||
{
|
||||
public :
|
||||
LockAddErase(std::atomic_flag& bAddEraseOn, bool bUse = true): m_bAddEraseOn( bAddEraseOn), m_bUse( bUse)
|
||||
{ if ( ! m_bUse) return ;
|
||||
while ( m_bAddEraseOn.test_and_set()) {
|
||||
this_thread::sleep_for( chrono::nanoseconds{ 1}) ;
|
||||
}
|
||||
} ;
|
||||
|
||||
~LockAddErase( void)
|
||||
{ if ( ! m_bUse) return ;
|
||||
m_bAddEraseOn.clear() ;
|
||||
} ;
|
||||
|
||||
private :
|
||||
std::atomic_flag& m_bAddEraseOn ;
|
||||
bool m_bUse ;
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IGeomDB*
|
||||
CreateGeomDB( void)
|
||||
@@ -39,20 +62,25 @@ CreateGeomDB( void)
|
||||
// verifico la chiave e le opzioni
|
||||
unsigned int nOpt1, nOpt2 ;
|
||||
int nOptExpDays ;
|
||||
int nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
if ( ! GetEGkNetHwKey())
|
||||
nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
// controllo i risultati
|
||||
if ( nRet != KEY_OK && ! EqualNoCase( GetEGkKey(), "EGkBase")) {
|
||||
if ( nRet != KEY_OK) {
|
||||
string sErr = "Error on Key (GKC/" + ToString( nRet) + ")" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return nullptr ;
|
||||
}
|
||||
if ( (nOpt1 & KEYOPT_EGK_BASE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
if ( ( nOpt1 & KEYOPT_EGK_BASE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
string sErr = "Error on Key (GKC/OPT)" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
|
||||
// creo il GeomDB
|
||||
return static_cast<IGeomDB*> ( new( nothrow) GeomDB) ;
|
||||
}
|
||||
@@ -62,6 +90,7 @@ CreateGeomDB( void)
|
||||
//----------------------------------------------------------------------------
|
||||
GeomDB::GeomDB( void)
|
||||
{
|
||||
m_bAddEraseOn.clear() ;
|
||||
m_GrpRadix.SetGeomDB( this) ;
|
||||
m_GrpRadix.m_nId = GDB_ID_ROOT ;
|
||||
m_GrpRadix.SetMaterial( Color()) ;
|
||||
@@ -274,14 +303,18 @@ GeomDB::Save( int nId, const string& sFileOut, int nFlag) const
|
||||
// verifico la chiave e le opzioni
|
||||
unsigned int nOpt1, nOpt2 ;
|
||||
int nOptExpDays ;
|
||||
int nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
if ( ! GetEGkNetHwKey())
|
||||
nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
// controllo i risultati
|
||||
if ( nRet != KEY_OK) {
|
||||
string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
}
|
||||
if ( (nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
if ( ( nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
string sErr = "Error on Key (GKS/OPT)" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
@@ -384,14 +417,18 @@ GeomDB::Save( const INTVECTOR& vId, const string& sFileOut, int nFlag) const
|
||||
// verifico la chiave e le opzioni
|
||||
unsigned int nOpt1, nOpt2 ;
|
||||
int nOptExpDays ;
|
||||
int nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
if ( ! GetEGkNetHwKey())
|
||||
nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV,
|
||||
nOpt1, nOpt2, nOptExpDays) ;
|
||||
// controllo i risultati
|
||||
if ( nRet != KEY_OK) {
|
||||
string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
}
|
||||
if ( (nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
if ( ( nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) {
|
||||
string sErr = "Error on Key (GKS/OPT)" ;
|
||||
LOG_ERROR( GetEGkLogger(), sErr.c_str()) ;
|
||||
return false ;
|
||||
@@ -416,7 +453,7 @@ GeomDB::Save( const INTVECTOR& vId, const string& sFileOut, int nFlag) const
|
||||
return false ;
|
||||
|
||||
// ciclo sugli oggetti da esportare
|
||||
unordered_set<int> usSavedId ;
|
||||
INTUNORDSET usSavedId ;
|
||||
for ( const auto nId : vId) {
|
||||
|
||||
// se già salvato, passo oltre
|
||||
@@ -513,7 +550,10 @@ GeomDB::SaveHeader( NgeWriter& ngeOut) const
|
||||
|
||||
// LockId del sistema come commento
|
||||
string sLockId ;
|
||||
if ( ! GetLockId( sLockId)) {
|
||||
if ( GetEGkNetHwKey()) {
|
||||
sLockId = "NET-000000" ;
|
||||
}
|
||||
else if ( ! GetLockId( sLockId)) {
|
||||
LOG_ERROR( GetEGkLogger(), "Error on Key (1)")
|
||||
return false ;
|
||||
}
|
||||
@@ -578,25 +618,32 @@ GeomDB::GetGdbObj( int nId) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bTestId)
|
||||
GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLockAddErase, bool bTestId)
|
||||
{
|
||||
// verifico validità oggetto puntato
|
||||
if ( pGObj == nullptr)
|
||||
return false ;
|
||||
|
||||
// se richiesta, verifica validità e unicità del nome
|
||||
if ( bTestId && ( pGObj->m_nId <= GDB_ID_ROOT || ExistsObj( pGObj->m_nId)))
|
||||
// verifico validità del riferimento
|
||||
if ( nRefId < GDB_ID_ROOT)
|
||||
return false ;
|
||||
|
||||
// oggetto e riferimento non possono essere la stessa cosa
|
||||
if ( pGObj->m_nId == nRefId)
|
||||
return ( ! IS_GDB_SON( nSonBeforeAfter)) ;
|
||||
|
||||
// verifico unicità esecuzione, se necessaria
|
||||
LockAddErase Lock( m_bAddEraseOn, bLockAddErase) ;
|
||||
|
||||
// cerco il riferimento
|
||||
GdbObj* pGRef = GetGdbObj( nRefId) ;
|
||||
if ( pGRef == nullptr)
|
||||
return false ;
|
||||
|
||||
// se richiesta, verifica validità e unicità del nome
|
||||
if ( bTestId && ( pGObj->m_nId <= GDB_ID_ROOT || ExistsObj( pGObj->m_nId)))
|
||||
return false ;
|
||||
|
||||
// assegno il riferimento al DB geometrico
|
||||
pGObj->SetGeomDB( this) ;
|
||||
|
||||
@@ -612,7 +659,7 @@ GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bTe
|
||||
}
|
||||
// inserisco come figlio, in testa alla lista del padre
|
||||
else if ( nSonBeforeAfter == GDB_FIRST_SON){
|
||||
GdbGroup* pGroup = dynamic_cast<GdbGroup*> ( pGRef) ;
|
||||
GdbGroup* pGroup = ::GetGdbGroup( pGRef) ;
|
||||
if ( pGroup == nullptr)
|
||||
return false ;
|
||||
// inserisco in testa alla lista del padre
|
||||
@@ -621,7 +668,7 @@ GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bTe
|
||||
}
|
||||
// inserisco come figlio, in coda alla lista del padre
|
||||
else {
|
||||
GdbGroup* pGroup = dynamic_cast<GdbGroup*> ( pGRef) ;
|
||||
GdbGroup* pGroup = ::GetGdbGroup( pGRef) ;
|
||||
if ( pGroup == nullptr)
|
||||
return false ;
|
||||
// inserisco in coda alla lista del padre
|
||||
@@ -650,6 +697,8 @@ GeomDB::InsertGroup( int nId, int nRefId, int nSonBeforeAfter, const Frame3d& fr
|
||||
// verifico validità apparente RefId
|
||||
if ( nRefId < GDB_ID_ROOT)
|
||||
return GDB_ID_NULL ;
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
// verifico validità Id
|
||||
if ( nId <= GDB_ID_ROOT)
|
||||
nId = m_IdManager.GetNewId() ;
|
||||
@@ -664,7 +713,7 @@ GeomDB::InsertGroup( int nId, int nRefId, int nSonBeforeAfter, const Frame3d& fr
|
||||
// assegno riferimento
|
||||
pGdbGroup->SetFrame( frFrame) ;
|
||||
// inserisco nel DB
|
||||
if ( ! InsertInGeomDB( pGdbGroup, nRefId, nSonBeforeAfter)) {
|
||||
if ( ! InsertInGeomDB( pGdbGroup, nRefId, nSonBeforeAfter, false)) {
|
||||
delete pGdbGroup ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
@@ -685,6 +734,8 @@ GeomDB::InsertGeoObj( int nId, int nRefId, int nSonBeforeAfter, IGeoObj* pGeoObj
|
||||
{
|
||||
// assegno GeoObj a gestore puntatore con rilascio automatico
|
||||
PtrOwner<IGeoObj> pRPGeoObj( pGeoObj) ;
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
// verifico validità identificativo
|
||||
if ( nId <= GDB_ID_ROOT)
|
||||
nId = m_IdManager.GetNewId() ;
|
||||
@@ -702,7 +753,7 @@ GeomDB::InsertGeoObj( int nId, int nRefId, int nSonBeforeAfter, IGeoObj* pGeoObj
|
||||
// assegno dati
|
||||
pGdbGeo->m_pGeoObj = Release( pRPGeoObj) ;
|
||||
// inserisco nel DB
|
||||
if ( ! InsertInGeomDB( pGdbGeo, nRefId, nSonBeforeAfter)) {
|
||||
if ( ! InsertInGeomDB( pGdbGeo, nRefId, nSonBeforeAfter, false)) {
|
||||
delete pGdbGeo ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
@@ -1185,6 +1236,9 @@ GeomDB::GetRefBBox( int nId, const Frame3d& frRef, BBox3d& b3Ref, int nFlag) con
|
||||
int
|
||||
GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// verifico Id destinazione
|
||||
if ( nIdDest <= GDB_ID_ROOT)
|
||||
nIdDest = m_IdManager.GetNewId() ;
|
||||
@@ -1227,7 +1281,7 @@ GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGl
|
||||
}
|
||||
|
||||
// inserisco nel DB (non rilascio il puntatore)
|
||||
if ( ! InsertInGeomDB( pGdODest, nRefId, nSonBeforeAfter))
|
||||
if ( ! InsertInGeomDB( pGdODest, nRefId, nSonBeforeAfter, false))
|
||||
return GDB_ID_NULL ;
|
||||
|
||||
// rilascio il puntatore
|
||||
@@ -1239,10 +1293,17 @@ GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGl
|
||||
bool
|
||||
GeomDB::Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// l'oggetto e il riferimento non possono coincidere
|
||||
// verifico validità del riferimento
|
||||
if ( nRefId < GDB_ID_ROOT)
|
||||
return false ;
|
||||
|
||||
// l'oggetto e il riferimento non possono coincidere
|
||||
if ( nId == nRefId)
|
||||
return ( ! IS_GDB_SON( nSonBeforeAfter)) ;
|
||||
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// verifico esistenza dell'oggetto
|
||||
GdbObj* pGdbObj = GetGdbObj( nId) ;
|
||||
if ( pGdbObj == nullptr)
|
||||
@@ -1286,7 +1347,7 @@ GeomDB::Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
pGdbObj->Remove() ;
|
||||
|
||||
// lo inserisco nella posizione opportuna
|
||||
if ( ! InsertInGeomDB( pGdbObj, nRefId, nSonBeforeAfter, false)) {
|
||||
if ( ! InsertInGeomDB( pGdbObj, nRefId, nSonBeforeAfter, false, false)) {
|
||||
// in caso di errore (condizione assai remota qui) cancello tutto
|
||||
m_IdManager.RemoveObj( pGdbObj->m_nId) ;
|
||||
m_SelManager.RemoveObj( pGdbObj) ;
|
||||
@@ -1367,9 +1428,14 @@ GeomDB::GetNewId( void) const
|
||||
bool
|
||||
GeomDB::ChangeId( int nId, int nNewId)
|
||||
{
|
||||
// se Id non validi, ritorno errore
|
||||
if ( nId <= GDB_ID_ROOT || nNewId <= GDB_ID_ROOT)
|
||||
return false ;
|
||||
// se Id identici, non faccio alcunché
|
||||
if ( nNewId == nId)
|
||||
return true ;
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
// verifico nuovo Id
|
||||
if ( ExistsObj( nNewId))
|
||||
return false ;
|
||||
@@ -1410,7 +1476,10 @@ GeomDB::Erase( GdbObj* pGdbObj)
|
||||
if ( pGdbObj == nullptr || pGdbObj == &m_GrpRadix)
|
||||
return false ;
|
||||
|
||||
// notifico eventuale UserObj
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// notifico eventuale UserObj
|
||||
if ( pGdbObj->m_pUserObj != nullptr) {
|
||||
// recupero il successivo
|
||||
const GdbObj* pGdbNext = pGdbObj->GetNext() ;
|
||||
@@ -1435,6 +1504,10 @@ GeomDB::RemoveGeoObjAndErase( int nId)
|
||||
// non si può cancellare il gruppo radice (escludo anche Id non validi)
|
||||
if ( nId <= GDB_ID_ROOT)
|
||||
return nullptr ;
|
||||
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// recupero l'oggetto geometrico
|
||||
GdbGeo* pGdbGeo = ::GetGdbGeo( m_IdManager.FindObj( nId)) ;
|
||||
if ( pGdbGeo == nullptr)
|
||||
@@ -1442,6 +1515,7 @@ GeomDB::RemoveGeoObjAndErase( int nId)
|
||||
IGeoObj* pGeoObj = pGdbGeo->m_pGeoObj ;
|
||||
// annullo il riferimento alla geometria nell'entità
|
||||
pGdbGeo->m_pGeoObj = nullptr ;
|
||||
|
||||
// tolgo dalla lista e disalloco
|
||||
pGdbGeo->Remove() ;
|
||||
delete pGdbGeo ;
|
||||
@@ -1477,6 +1551,10 @@ GeomDB::EmptyGroup( GdbObj* pGdbObj)
|
||||
GdbGroup* pGrp = ::GetGdbGroup( pGdbObj) ;
|
||||
if ( pGrp == nullptr)
|
||||
return false ;
|
||||
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// lo svuoto
|
||||
return pGrp->Clear() ;
|
||||
}
|
||||
@@ -2521,6 +2599,9 @@ GeomDB::GetCalcMaterial( const GdbObj* pGdbObj, Material& mMat) const
|
||||
Color cCol ;
|
||||
if ( pGdbObj->GetCalcMaterial( cCol)) {
|
||||
mMat.Set( cCol) ;
|
||||
Color cDiff = cCol ;
|
||||
cDiff.Intensify( 1.25) ;
|
||||
mMat.SetDiffuse( cDiff) ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
@@ -2874,6 +2955,19 @@ GeomDB::RemoveInfo( int nId, const string& sKey)
|
||||
return pGdbObj->RemoveInfo( sKey) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::GetAllInfo( int nId, STRVECTOR& vsInfo) const
|
||||
{
|
||||
// recupero l'oggetto
|
||||
const GdbObj* pGdbObj = GetGdbObj( nId) ;
|
||||
if ( pGdbObj == nullptr)
|
||||
return false ;
|
||||
|
||||
// recupero tutte le Info
|
||||
return pGdbObj->GetAllInfo( vsInfo) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::CopyAllInfoFrom( int nId, int nSouId)
|
||||
@@ -2883,7 +2977,7 @@ GeomDB::CopyAllInfoFrom( int nId, int nSouId)
|
||||
if ( pGdbObj == nullptr)
|
||||
return false ;
|
||||
// recupero l'oggetto sorgente
|
||||
GdbObj* pGdbObjSou = GetGdbObj( nSouId) ;
|
||||
const GdbObj* pGdbObjSou = GetGdbObj( nSouId) ;
|
||||
if ( pGdbObjSou == nullptr)
|
||||
return false ;
|
||||
|
||||
@@ -2896,6 +2990,51 @@ GeomDB::CopyAllInfoFrom( int nId, int nSouId)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Stipple (significativo solo per curve)
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::DumpStipple( int nId, string& sOut, bool bMM, const char* szNewLine) const
|
||||
{
|
||||
// recupero l'oggetto
|
||||
const GdbObj* pGdbObj = GetGdbObj( nId) ;
|
||||
if ( pGdbObj == nullptr)
|
||||
return false ;
|
||||
// eseguo il dump
|
||||
if ( pGdbObj->m_nStpFactor != 0) {
|
||||
// nome della texture
|
||||
sOut += "Stipple=" ;
|
||||
sOut += ToString( pGdbObj->m_nStpFactor) ;
|
||||
sOut += "-" + ToString( pGdbObj->m_nStpPattern, 1, 16) ;
|
||||
sOut += szNewLine ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::SetStipple( int nId, int nFactor, int nPattern)
|
||||
{
|
||||
// recupero l'oggetto
|
||||
GdbObj* pGdbObj = GetGdbObj( nId) ;
|
||||
if ( pGdbObj == nullptr)
|
||||
return false ;
|
||||
// imposto lo stipple
|
||||
return pGdbObj->SetStipple( nFactor, nPattern) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::GetStipple( int nId, int& nFactor, int& nPattern) const
|
||||
{
|
||||
// recupero l'oggetto
|
||||
const GdbObj* pGdbObj = GetGdbObj( nId) ;
|
||||
if ( pGdbObj == nullptr)
|
||||
return false ;
|
||||
// recupero lo stipple
|
||||
return pGdbObj->GetStipple( nFactor, nPattern) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// TextureData
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -2907,7 +3046,7 @@ GeomDB::DumpTextureData( int nId, string& sOut, bool bMM, const char* szNewLine)
|
||||
if ( pGdbObj == nullptr)
|
||||
return false ;
|
||||
// eseguo il dump
|
||||
if ( pGdbObj->m_pTxrData != nullptr)
|
||||
if ( pGdbObj->m_pTxrData != nullptr)
|
||||
return pGdbObj->m_pTxrData->Dump( *this, sOut, bMM, szNewLine) ;
|
||||
else
|
||||
return true ;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2014
|
||||
// EgalTech 2013-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : GeomDB.h Data : 03.12.14 Versione : 1.5l1
|
||||
// File : GeomDB.h Data : 09.07.23 Versione : 2.5g1
|
||||
// Contenuto : Dichiarazione della classe GeomDB.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 22.01.13 DS Creazione modulo.
|
||||
// 03.12.14 DS Aggiunta gestione riferimento di griglia.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "SelManager.h"
|
||||
#include "GdbMaterialMgr.h"
|
||||
#include "/EgtDev/Include/EGkGeomDB.h"
|
||||
#include <atomic>
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class GeomDB : public IGeomDB
|
||||
@@ -179,7 +180,12 @@ class GeomDB : public IGeomDB
|
||||
bool GetInfo( int nId, const std::string& sKey, STRVECTOR& vsInfo) const override ;
|
||||
bool ExistsInfo( int nId, const std::string& sKey) const override ;
|
||||
bool RemoveInfo( int nId, const std::string& sKey) override ;
|
||||
bool GetAllInfo( int nId, STRVECTOR& vsInfo) const override ;
|
||||
bool CopyAllInfoFrom( int nId, int nSouId) override ;
|
||||
// Stipple (significativo solo per curve)
|
||||
bool DumpStipple( int nId, std::string& sOut, bool bMM = true, const char* szNewLine = "\n") const override ;
|
||||
bool SetStipple( int nId, int nFactor, int nPattern) override ;
|
||||
bool GetStipple( int nId, int& nFactor, int& nPattern) const override ;
|
||||
// TextureData
|
||||
bool DumpTextureData( int nId, std::string& sOut, bool bMM = true, const char* szNewLine = "\n") const override ;
|
||||
bool SetTextureName( int nId, const std::string& sTxrName) override ;
|
||||
@@ -221,14 +227,14 @@ class GeomDB : public IGeomDB
|
||||
GdbObj* GetGdbObj( int nId) ;
|
||||
const GdbObj* GetGdbObj( int nId) const ;
|
||||
GdbGeo* GetGdbGeo( int nId)
|
||||
{ return dynamic_cast<GdbGeo*>( GetGdbObj( nId)) ; }
|
||||
{ return ::GetGdbGeo( GetGdbObj( nId)) ; }
|
||||
const GdbGeo* GetGdbGeo( int nId) const
|
||||
{ return dynamic_cast<const GdbGeo*>( GetGdbObj( nId)) ; }
|
||||
{ return ::GetGdbGeo( GetGdbObj( nId)) ; }
|
||||
GdbGroup* GetGdbGroup( int nId)
|
||||
{ return dynamic_cast<GdbGroup*>( GetGdbObj( nId)) ; }
|
||||
{ return ::GetGdbGroup( GetGdbObj( nId)) ; }
|
||||
const GdbGroup* GetGdbGroup( int nId) const
|
||||
{ return dynamic_cast<const GdbGroup*>( GetGdbObj( nId)) ; }
|
||||
bool InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bTestId = true) ;
|
||||
{ return ::GetGdbGroup( GetGdbObj( nId)) ; }
|
||||
bool InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLockAddErase = true, bool bTestId = true) ;
|
||||
int Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGlob) ;
|
||||
bool Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob) ;
|
||||
bool Erase( GdbObj* pGObj) ;
|
||||
@@ -252,10 +258,11 @@ class GeomDB : public IGeomDB
|
||||
{ return m_IterManager.RemoveGdbIterator( pIter) ; }
|
||||
|
||||
private :
|
||||
IdManager m_IdManager ; // gestore del nuovo Id
|
||||
IterManager m_IterManager ; // gestore lista iteratori attivi
|
||||
SelManager m_SelManager ; // gestore lista oggetti selezionati
|
||||
GdbMaterialMgr m_MatManager ; // gestore lista materiali
|
||||
GdbGroup m_GrpRadix ; // gruppo radice di tutto il DB
|
||||
Frame3d m_GridFrame ; // riferimento della griglia
|
||||
IdManager m_IdManager ; // gestore del nuovo Id
|
||||
IterManager m_IterManager ; // gestore lista iteratori attivi
|
||||
SelManager m_SelManager ; // gestore lista oggetti selezionati
|
||||
GdbMaterialMgr m_MatManager ; // gestore lista materiali
|
||||
GdbGroup m_GrpRadix ; // gruppo radice di tutto il DB
|
||||
Frame3d m_GridFrame ; // riferimento della griglia
|
||||
std::atomic_flag m_bAddEraseOn ; // flag esecuzione inserimento o cancellazione in corso (per multi thread)
|
||||
} ;
|
||||
|
||||
+759
@@ -0,0 +1,759 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2018
|
||||
//----------------------------------------------------------------------------
|
||||
// File : HashGrids1d.cpp Data : 02.05.22 Versione : 2.4e1
|
||||
// Contenuto : Funzioni della classe HashGrids1d.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 04.07.15 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DllMain.h"
|
||||
#include "/EgtDev/Include/EGkHashGrids1d.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const size_t CellCount = 16 ;
|
||||
const size_t cellVectorSize = 16 ;
|
||||
const size_t occupiedCellsVectorSize = 256 ;
|
||||
const size_t minimalGridDensity = 1 ;
|
||||
const size_t gridActivationThreshold = 64 ;
|
||||
const double hierarchyFactor = 2 ;
|
||||
const double MIN_CELL_SIZE = 5.0 ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// HashGrid1d
|
||||
//----------------------------------------------------------------------------
|
||||
class HashGrid1d
|
||||
{
|
||||
private :
|
||||
struct Cell
|
||||
{
|
||||
HashGrids1d::PtrObjVector* m_Objs ; // Vettore dei puntatori agli oggetti nella cella, come puntatore
|
||||
int* m_neighborOffset ; // Puntatore ad array con offsets per accedere direttamente ai vicini
|
||||
size_t m_occupiedCellsId ; // Indice della cella nel vettore delle celle occupate
|
||||
Cell( void)
|
||||
: m_Objs( nullptr), m_neighborOffset( nullptr), m_occupiedCellsId( 0) {}
|
||||
} ;
|
||||
|
||||
typedef vector<Cell*> CellVector ;
|
||||
|
||||
public :
|
||||
explicit HashGrid1d( double dCellSpan) ;
|
||||
~HashGrid1d( void) ;
|
||||
double GetCellSpan( void) const
|
||||
{ return m_dCellSpan ; }
|
||||
void Add( HashGrids1d::ObjData& obj) ;
|
||||
void Remove( HashGrids1d::ObjData& obj) ;
|
||||
void Update( HashGrids1d::ObjData& obj) ;
|
||||
void Find( const BBox3d& b3Test, INTVECTOR& vnIds) ;
|
||||
void Clear( void) ;
|
||||
|
||||
private :
|
||||
void InitNeighborOffsets( void) ;
|
||||
size_t Hash( const Point3d& ptP) const ;
|
||||
void Add( HashGrids1d::ObjData& obj, Cell* cell) ;
|
||||
void Remove( HashGrids1d::ObjData& obj, Cell* cell) ;
|
||||
void Enlarge( void) ;
|
||||
static inline bool PowerOfTwo( size_t number) ;
|
||||
|
||||
private :
|
||||
Cell* m_cell ; // Vettore di celle della griglia
|
||||
|
||||
size_t m_CellCount ; // Numero di celle allocate in direzione Z
|
||||
|
||||
size_t m_HashMask ; // Maschera di bit per calcolo hash
|
||||
|
||||
size_t m_enlargementThreshold ; // Soglia corrente per incremetare le dimensioni della griglia
|
||||
|
||||
double m_dCellSpan ; // Dimensione di una cella (cubica) della griglia
|
||||
double m_dInvCellSpan ; // Inverso della dimensione di una cella
|
||||
|
||||
CellVector m_occupiedCells ; // Vettore delle celle occupate in questa griglia
|
||||
|
||||
size_t m_objCount ; // Numero di oggetti presenti in questa griglia
|
||||
|
||||
int m_stdNeighborOffset[3] ; // Array degli offset standard per le adiacenze
|
||||
|
||||
BBox3d m_b3Grid ; // Box totale degli oggetti inseriti in questa griglia
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
HashGrid1d::HashGrid1d( double dCellSpan)
|
||||
{
|
||||
// Initialization of all member variables and ...
|
||||
m_CellCount = PowerOfTwo( CellCount) ? CellCount : 16 ;
|
||||
|
||||
m_HashMask = m_CellCount - 1 ;
|
||||
|
||||
m_enlargementThreshold = m_CellCount / minimalGridDensity ;
|
||||
|
||||
// allocazione dell'array lineare che rappresenta lo hash grid.
|
||||
m_cell = new Cell[ m_CellCount] ;
|
||||
|
||||
// ogni cella è già inizializzata come vuota
|
||||
// imposto gli offset ai vicini
|
||||
InitNeighborOffsets() ;
|
||||
|
||||
m_dCellSpan = max( dCellSpan, 10 * EPS_SMALL) ;
|
||||
m_dInvCellSpan = 1. / dCellSpan ;
|
||||
|
||||
m_occupiedCells.reserve( occupiedCellsVectorSize) ;
|
||||
|
||||
m_objCount = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
HashGrid1d::~HashGrid1d( void)
|
||||
{
|
||||
Clear() ;
|
||||
|
||||
for ( Cell* pCell = m_cell ; pCell < m_cell + m_CellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
}
|
||||
delete[] m_cell ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrid1d::Add( HashGrids1d::ObjData& obj)
|
||||
{
|
||||
// If adding the body will cause the total number of bodies assigned to this grid to exceed the
|
||||
// enlargement threshold, the size of this hash grid must be increased.
|
||||
if ( m_objCount == m_enlargementThreshold)
|
||||
Enlarge() ;
|
||||
|
||||
// Calculate (and store) the hash value (= the body's cell association) and ...
|
||||
size_t h = Hash( obj.box.GetMin()) ;
|
||||
obj.nHash = h ;
|
||||
|
||||
// ... insert the body into the corresponding cell.
|
||||
Cell* pCell = m_cell + h ;
|
||||
Add( obj, pCell) ;
|
||||
++ m_objCount ;
|
||||
|
||||
// Aggiorno box di griglia
|
||||
m_b3Grid.Add( obj.box) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrid1d::Remove( HashGrids1d::ObjData& obj)
|
||||
{
|
||||
// The stored hash value (= the body's cell association) is used in order to directly access the
|
||||
// cell from which this body will be removed.
|
||||
Cell* pCell = m_cell + obj.nHash ;
|
||||
Remove( obj, pCell) ;
|
||||
-- m_objCount ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrid1d::Update( HashGrids1d::ObjData& obj)
|
||||
{
|
||||
// The hash value is recomputed based on the body's current spatial location.
|
||||
size_t newHash = Hash( obj.box.GetMin()) ;
|
||||
size_t oldHash = obj.nHash ;
|
||||
|
||||
// If this new hash value is identical to the hash value of the previous time step, the body
|
||||
// remains assigned to its current grid cell.
|
||||
if ( newHash == oldHash)
|
||||
return ;
|
||||
|
||||
// Only if the hash value changes, the cell association has to be changed, too - meaning, the
|
||||
// body has to be removed from its currently assigned cell and ...
|
||||
Cell* pCell = m_cell + oldHash ;
|
||||
Remove( obj, pCell) ;
|
||||
|
||||
obj.nHash = newHash ;
|
||||
|
||||
// ... stored in the cell that corresponds to the new hash value.
|
||||
pCell = m_cell + newHash ;
|
||||
Add( obj, pCell) ;
|
||||
|
||||
// Aggiorno box di griglia
|
||||
m_b3Grid.Add( obj.box) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrid1d::Find( const BBox3d& b3Test, INTVECTOR& vnIds)
|
||||
{
|
||||
// Limito il box a quello di griglia
|
||||
BBox3d b3Int ;
|
||||
if ( ! b3Test.FindIntersection( m_b3Grid, b3Int))
|
||||
return ;
|
||||
|
||||
// Recupero gli estremi del box
|
||||
Point3d ptMin ;
|
||||
double dXDim, dYDim, dZDim ;
|
||||
if ( ! b3Int.GetMinDim( ptMin, dXDim, dYDim, dZDim))
|
||||
return ;
|
||||
// Sposto p.to minimo in meno di una cella (oggetti possono occupare 2 celle) e allargo tutto di EPS_SMALL
|
||||
ptMin -= Vector3d( 0, 0, 1) * ( m_dCellSpan + EPS_SMALL) ;
|
||||
dZDim += m_dCellSpan + 2 * EPS_SMALL ;
|
||||
|
||||
// Numero di celle da esplorare sull'asse Z
|
||||
int nZSpan = min( static_cast<int>( ceil( dZDim * m_dInvCellSpan)), int( m_CellCount)) ;
|
||||
|
||||
//string sOut = "Celle=" + ToString( int( m_CellCount)) + " Occupate=" + ToString( int(m_occupiedCells.size())) + " Span=" + ToString( nZSpan) ;
|
||||
//LOG_INFO( GetEGkLogger(), sOut.c_str()) ;
|
||||
|
||||
// Se conviene verificare queste celle
|
||||
if ( nZSpan < 5 * int( m_occupiedCells.size())) {
|
||||
// cella di base
|
||||
int nZ = static_cast<int>( Hash( ptMin)) ;
|
||||
for ( int i = 0 ; i <= nZSpan ; ++ i) {
|
||||
// inserisco in lista gli oggetti della cella
|
||||
if ( m_cell[nZ].m_Objs != nullptr) {
|
||||
for ( auto pObj : *( m_cell[nZ].m_Objs)) {
|
||||
if ( b3Int.Overlaps( pObj->box))
|
||||
vnIds.push_back( pObj->nId) ;
|
||||
}
|
||||
}
|
||||
// passo alla successiva in Z+
|
||||
nZ += m_cell[nZ].m_neighborOffset[2] ;
|
||||
}
|
||||
}
|
||||
|
||||
// altrimenti verifico direttamente tutte e sole quelle occupate
|
||||
else {
|
||||
// ciclo sulle celle occupate
|
||||
for ( auto cell : m_occupiedCells) {
|
||||
// inserisco in lista gli oggetti della cella
|
||||
if ( cell->m_Objs != nullptr) {
|
||||
for ( auto pObj : *(cell->m_Objs)) {
|
||||
if ( b3Int.Overlaps( pObj->box))
|
||||
vnIds.push_back( pObj->nId) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrid1d::Clear( void)
|
||||
{
|
||||
for ( auto cell : m_occupiedCells) {
|
||||
delete cell->m_Objs ;
|
||||
cell->m_Objs = nullptr ;
|
||||
}
|
||||
m_occupiedCells.clear() ;
|
||||
m_objCount = 0 ;
|
||||
m_b3Grid.Reset() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrid1d::InitNeighborOffsets( void)
|
||||
{
|
||||
int nc = static_cast<int>( m_CellCount) ;
|
||||
|
||||
// Initialization of the grid-global offset array that is valid for all inner cells in the hash grid.
|
||||
m_stdNeighborOffset[0] = -1 ;
|
||||
m_stdNeighborOffset[1] = 0 ;
|
||||
m_stdNeighborOffset[2] = 1 ;
|
||||
|
||||
// Allocation and initialization of the offset arrays of all the border cells. All inner cells
|
||||
// are set to point to the grid-global offset array.
|
||||
Cell* c = m_cell ;
|
||||
for ( int i = 0 ; i < nc ; ++ i, ++ c) {
|
||||
// cella di bordo
|
||||
if ( i == 0) {
|
||||
c->m_neighborOffset = new int[3] ;
|
||||
c->m_neighborOffset[0] = nc - 1 ;
|
||||
c->m_neighborOffset[1] = 0 ;
|
||||
c->m_neighborOffset[2] = 1 ;
|
||||
}
|
||||
else if ( i == nc - 1) {
|
||||
c->m_neighborOffset = new int[3] ;
|
||||
c->m_neighborOffset[0] = -1 ;
|
||||
c->m_neighborOffset[1] = 0 ;
|
||||
c->m_neighborOffset[2] = -nc + 1 ;
|
||||
}
|
||||
// cella interna
|
||||
else {
|
||||
c->m_neighborOffset = m_stdNeighborOffset ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
size_t
|
||||
HashGrid1d::Hash( const Point3d& ptP) const
|
||||
{
|
||||
size_t nHash ;
|
||||
if ( ptP.z < 0) {
|
||||
double i = ( - ptP.z ) * m_dInvCellSpan ;
|
||||
nHash = m_CellCount - 1 - ( static_cast<size_t>( i ) & m_HashMask) ;
|
||||
}
|
||||
else {
|
||||
double i = ptP.z * m_dInvCellSpan ;
|
||||
nHash = static_cast<size_t>( i ) & m_HashMask ;
|
||||
}
|
||||
|
||||
return nHash ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrid1d::Add( HashGrids1d::ObjData& obj, Cell* cell)
|
||||
{
|
||||
// If this cell is already occupied by other bodies, which means the pointer to the body
|
||||
// container holds a valid address and thus the container itself is properly initialized, then
|
||||
// the body is simply added to this already existing body container. Note that the index position
|
||||
// is memorized (=> "body->setCellId()") in order to ensure constant time removal.
|
||||
if ( cell->m_Objs != nullptr) {
|
||||
obj.nCellId = cell->m_Objs->size() ;
|
||||
cell->m_Objs->push_back( &obj) ;
|
||||
}
|
||||
|
||||
// If, however, the cell is still empty, then the object container, first of all, must be created
|
||||
// (i.e., allocated) and properly initialized (i.e., sufficient initial storage capacity must be
|
||||
// reserved). Furthermore, the cell must be inserted into the grid-global vector 'm_occupiedCells'
|
||||
// in which all cells that are currently occupied by bodies are recorded.
|
||||
else {
|
||||
cell->m_Objs = new HashGrids1d::PtrObjVector ;
|
||||
cell->m_Objs->reserve( cellVectorSize) ;
|
||||
|
||||
obj.nCellId = 0 ;
|
||||
cell->m_Objs->push_back( &obj) ;
|
||||
|
||||
cell->m_occupiedCellsId = m_occupiedCells.size() ;
|
||||
m_occupiedCells.push_back( cell) ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrid1d::Remove( HashGrids1d::ObjData& obj, Cell* cell )
|
||||
{
|
||||
// If the body is the last body that is stored in this cell ...
|
||||
if ( cell->m_Objs->size() == 1) {
|
||||
// ... the cell's body container is destroyed and ...
|
||||
delete cell->m_Objs ;
|
||||
cell->m_Objs = nullptr ;
|
||||
|
||||
// ... the cell is removed from the grid-global vector 'm_occupiedCells' that records all
|
||||
// body-occupied cells. Since the cell memorized its index (=> 'm_occupiedCellsId') in this
|
||||
// vector, it can be removed in constant time, O(1).
|
||||
if ( cell->m_occupiedCellsId == m_occupiedCells.size() - 1) {
|
||||
m_occupiedCells.pop_back() ;
|
||||
}
|
||||
else {
|
||||
Cell* lastCell = m_occupiedCells.back() ;
|
||||
m_occupiedCells.pop_back() ;
|
||||
lastCell->m_occupiedCellsId = cell->m_occupiedCellsId ;
|
||||
m_occupiedCells[ cell->m_occupiedCellsId ] = lastCell ;
|
||||
}
|
||||
}
|
||||
// If the body is *not* the last body that is stored in this cell ...
|
||||
else {
|
||||
size_t cellId = obj.nCellId ;
|
||||
|
||||
// ... the body is removed from the cell's body container. Since the body memorized its
|
||||
// index (=> 'cellId') in this container, it can be removed in constant time, O(1).
|
||||
if ( cellId == cell->m_Objs->size() - 1) {
|
||||
cell->m_Objs->pop_back() ;
|
||||
}
|
||||
else {
|
||||
HashGrids1d::ObjData* lastElement = cell->m_Objs->back() ;
|
||||
cell->m_Objs->pop_back() ;
|
||||
lastElement->nCellId = cellId ;
|
||||
(*cell->m_Objs)[ cellId] = lastElement ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrid1d::Enlarge( void)
|
||||
{
|
||||
HashGrids1d::PtrObjVector PObjVecTemp ;
|
||||
PObjVecTemp.reserve( m_objCount) ;
|
||||
|
||||
// All objs that are assigned to this grid are temporarily removed, ...
|
||||
for ( auto cell = m_occupiedCells.begin() ; cell < m_occupiedCells.end() ; ++ cell) {
|
||||
HashGrids1d::PtrObjVector* cellBodies = (*cell)->m_Objs ;
|
||||
for ( auto e = cellBodies->begin() ; e < cellBodies->end() ; ++ e) {
|
||||
PObjVecTemp.push_back( *e) ;
|
||||
}
|
||||
}
|
||||
|
||||
// ... the grid's current data structures are deleted, ...
|
||||
Clear() ;
|
||||
|
||||
for ( auto pCell = m_cell ; pCell < m_cell + m_CellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
}
|
||||
delete[] m_cell ;
|
||||
|
||||
// ... the number of cells is doubled in each coordinate direction, ...
|
||||
m_CellCount *= 2 ;
|
||||
m_HashMask = m_CellCount - 1 ;
|
||||
|
||||
// ... a new threshold for enlarging this hash grid is set, ...
|
||||
m_enlargementThreshold = m_CellCount / minimalGridDensity ;
|
||||
|
||||
// ... a new linear array of cells representing this enlarged hash grid is allocated and ...
|
||||
m_cell = new Cell[ m_CellCount] ;
|
||||
|
||||
// ... initialized, and finally ...
|
||||
InitNeighborOffsets() ;
|
||||
|
||||
// ... all previously removed objs are reinserted.
|
||||
for ( auto p = PObjVecTemp.begin() ; p < PObjVecTemp.end() ; ++ p) {
|
||||
Add( **p) ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
HashGrid1d::PowerOfTwo( size_t number)
|
||||
{
|
||||
return ( ( number > 0) && ( ( number & ( number - 1)) == 0)) ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// HashGrids1d
|
||||
//----------------------------------------------------------------------------
|
||||
HashGrids1d::HashGrids1d( void)
|
||||
{
|
||||
try {
|
||||
// Finchè il numero di oggetti non supera la soglia non si usano le griglie
|
||||
m_nonGridObjs.reserve( gridActivationThreshold) ;
|
||||
m_bActivate = true ;
|
||||
m_bGridActive = false ;
|
||||
}
|
||||
catch(...) {
|
||||
LOG_ERROR( GetEGkLogger(), "Error in HashGrids1d constructor") ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
HashGrids1d::~HashGrids1d( void)
|
||||
{
|
||||
// Delete all grids that are stored in the grid hierarchy (=> m_GridList).
|
||||
for ( auto pGrid : m_GridList) {
|
||||
delete pGrid ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrids1d::SetActivationGrid( bool bActivate)
|
||||
{
|
||||
m_bActivate = bActivate ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
HashGrids1d::Add( int nObjId, const BBox3d& box)
|
||||
{
|
||||
try {
|
||||
// The body is marked as being added to 'm_objsToAdd' by setting the grid pointer to nullptr and
|
||||
// setting the cell-ID to '0'. Additionally, the hash value is used to memorize the body's
|
||||
// index position in the 'm_objsToAdd' vector.
|
||||
m_ObjsList.emplace_back( nObjId, box, nullptr, m_objsToAdd.size(), 0) ;
|
||||
|
||||
// inserisco nel Map
|
||||
m_ObjsMap.emplace( nObjId, &(m_ObjsList.back())) ;
|
||||
|
||||
// Temporarily add the body to 'm_objsToAdd'. As soon as "findContacts()" is called, all
|
||||
// bodies stored in 'm_objsToAdd' are finally inserted into the data structure.
|
||||
m_objsToAdd.push_back( &(m_ObjsList.back())) ;
|
||||
|
||||
// Aggiorno il box complessivo
|
||||
m_b3Objs.Add( box) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
catch(...) {
|
||||
LOG_ERROR( GetEGkLogger(), "Error in HashGrids1d::Add") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
HashGrids1d::Modify( int nObjId, const BBox3d& box)
|
||||
{
|
||||
// Cerco l'oggetto con l'Id voluto
|
||||
auto iIter = m_ObjsMap.find( nObjId) ;
|
||||
if ( iIter == m_ObjsMap.end())
|
||||
return false ;
|
||||
ObjData* pObj = iIter->second ;
|
||||
if ( pObj == nullptr)
|
||||
return false ;
|
||||
|
||||
// Modifico il suo box
|
||||
pObj->box = box ;
|
||||
|
||||
// Aggiorno il box complessivo
|
||||
m_b3Objs.Add( box) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
HashGrids1d::Remove( int nObjId)
|
||||
{
|
||||
// Cerco l'oggetto con l'Id voluto
|
||||
auto iIter = m_ObjsMap.find( nObjId) ;
|
||||
if ( iIter == m_ObjsMap.end())
|
||||
return false ;
|
||||
ObjData* pObj = iIter->second ;
|
||||
if ( pObj == nullptr)
|
||||
return false ;
|
||||
|
||||
// Recupero la griglia di appartenenza
|
||||
HashGrid1d* pGrid = pObj->pHGrid ;
|
||||
|
||||
// The body is stored in a hash grid from which it must be removed.
|
||||
if ( pGrid != nullptr) {
|
||||
pGrid->Remove( *pObj) ;
|
||||
}
|
||||
// The body's grid pointer is equal to nullptr.
|
||||
// => The body is either stored in 'm_objsToAdd' (-> cell-ID = 0) or 'm_nonGridObjs' (-> cell-ID = 1).
|
||||
else {
|
||||
if ( pObj->nCellId == 0) {
|
||||
// the body's hash value => index of this body in 'm_objsToAdd'
|
||||
if ( pObj->nHash == m_objsToAdd.size() - 1) {
|
||||
m_objsToAdd.pop_back() ;
|
||||
}
|
||||
else if ( pObj->nHash < m_objsToAdd.size()) {
|
||||
ObjData* pLastObj = m_objsToAdd.back() ;
|
||||
m_objsToAdd.pop_back() ;
|
||||
pLastObj->nHash = pObj->nHash ;
|
||||
m_objsToAdd[ pObj->nHash] = pLastObj ;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
else {
|
||||
// the body's hash value => index of this body in 'm_nonGridObjs'
|
||||
if ( pObj->nHash == m_nonGridObjs.size() - 1) {
|
||||
m_nonGridObjs.pop_back();
|
||||
}
|
||||
else if ( pObj->nHash < m_nonGridObjs.size()) {
|
||||
ObjData* pLastObj = m_nonGridObjs.back() ;
|
||||
m_nonGridObjs.pop_back() ;
|
||||
pLastObj->nHash = pObj->nHash ;
|
||||
m_nonGridObjs[ pObj->nHash] = pLastObj ;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
HashGrids1d::Update( void)
|
||||
{
|
||||
try {
|
||||
// Salvo stato di precedente attivazione delle griglie
|
||||
bool bGridActivePrev = m_bGridActive ;
|
||||
// Inseriamo gli oggetti presenti nel vettore m_objsToAdd
|
||||
if ( m_objsToAdd.size() > 0 ) {
|
||||
for ( auto pObj : m_objsToAdd) {
|
||||
if ( m_bGridActive)
|
||||
addGrid( *pObj) ;
|
||||
else
|
||||
addList( *pObj) ;
|
||||
}
|
||||
m_objsToAdd.clear() ;
|
||||
}
|
||||
// Aggiorniamo per eventuali modifiche agli oggetti già precedentemente presenti nelle griglie
|
||||
if ( bGridActivePrev) {
|
||||
for ( auto& Obj : m_ObjsList) {
|
||||
HashGrid1d* pGrid = Obj.pHGrid ;
|
||||
if ( pGrid != nullptr) {
|
||||
double dSize = 0 ;
|
||||
Obj.box.GetDiameter( dSize) ;
|
||||
double dCellSpan = pGrid->GetCellSpan() ;
|
||||
|
||||
if ( dSize >= dCellSpan || dSize < ( dCellSpan / hierarchyFactor)) {
|
||||
pGrid->Remove( Obj) ;
|
||||
addGrid( Obj) ;
|
||||
}
|
||||
else {
|
||||
pGrid->Update( Obj) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
catch(...) {
|
||||
LOG_ERROR( GetEGkLogger(), "Error in HashGrids1d::Update") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
HashGrids1d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
||||
{
|
||||
// pulisco il risultato
|
||||
vnIds.clear() ;
|
||||
vnIds.reserve( 128) ;
|
||||
|
||||
// limito con box globale
|
||||
BBox3d b3Int ;
|
||||
if ( ! b3Test.FindIntersection( m_b3Objs, b3Int))
|
||||
return false ;
|
||||
|
||||
// ricerca nelle griglie
|
||||
if ( m_bGridActive) {
|
||||
for ( auto pGrid : m_GridList)
|
||||
pGrid->Find( b3Int, vnIds) ;
|
||||
}
|
||||
|
||||
// ricerca negli oggetti fuori griglia
|
||||
for ( auto pObj : m_nonGridObjs) {
|
||||
if ( b3Int.Overlaps( pObj->box))
|
||||
vnIds.push_back( pObj->nId) ;
|
||||
}
|
||||
|
||||
// ordino il risultato ed elimino gli indici ripetuti
|
||||
sort( vnIds.begin(), vnIds.end()) ;
|
||||
vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
|
||||
|
||||
return ( vnIds.size() > 0) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrids1d::Clear( void)
|
||||
{
|
||||
for ( auto pGrid : m_GridList) {
|
||||
delete pGrid ;
|
||||
}
|
||||
m_GridList.clear() ;
|
||||
|
||||
m_bGridActive = false ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
|
||||
m_objsToAdd.clear() ;
|
||||
|
||||
m_b3Objs.Reset() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrids1d::addGrid( ObjData& obj)
|
||||
{
|
||||
double size = - 1 ;
|
||||
obj.box.GetDiameter( size) ;
|
||||
|
||||
// If the body is finite in size, it must be assigned to a grid with suitably sized cells.
|
||||
if ( size > - EPS_ZERO) {
|
||||
|
||||
size = max( size, MIN_CELL_SIZE) ;
|
||||
|
||||
HashGrid1d* pGrid = nullptr ;
|
||||
|
||||
if ( m_GridList.empty()) {
|
||||
// If no hash grid yet exists in the hierarchy, an initial hash grid is created
|
||||
// based on the body's size.
|
||||
|
||||
pGrid = new HashGrid1d( size * sqrt( hierarchyFactor)) ;
|
||||
}
|
||||
else {
|
||||
// Check the hierarchy for a hash grid with suitably sized cells - if such a grid does not
|
||||
// yet exist, it will be created.
|
||||
|
||||
double cellSpan = 0;
|
||||
for ( auto g = m_GridList.begin(); g != m_GridList.end(); ++ g) {
|
||||
pGrid = *g;
|
||||
cellSpan = pGrid->GetCellSpan();
|
||||
|
||||
if ( size < cellSpan) {
|
||||
cellSpan /= hierarchyFactor ;
|
||||
if ( size < cellSpan ) {
|
||||
while ( size < cellSpan)
|
||||
cellSpan /= hierarchyFactor ;
|
||||
pGrid = new HashGrid1d( cellSpan * hierarchyFactor) ;
|
||||
m_GridList.insert( g, pGrid) ;
|
||||
}
|
||||
|
||||
pGrid->Add( obj) ;
|
||||
obj.pHGrid = pGrid ;
|
||||
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
while ( size >= cellSpan)
|
||||
cellSpan *= hierarchyFactor ;
|
||||
pGrid = new HashGrid1d( cellSpan) ;
|
||||
}
|
||||
|
||||
pGrid->Add( obj) ;
|
||||
obj.pHGrid = pGrid ;
|
||||
|
||||
m_GridList.push_back( pGrid) ;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
// The body - which is infinite in size - is marked as being added to 'm_nonGridObjs' by setting
|
||||
// the grid pointer to nullptr and setting the cell-ID to '1'. Additionally, the hash value is used
|
||||
// to memorize the body's index position in the 'm_nonGridObjs' vector.
|
||||
|
||||
obj.pHGrid = nullptr ;
|
||||
obj.nHash = m_nonGridObjs.size() ;
|
||||
obj.nCellId = 1 ;
|
||||
|
||||
m_nonGridObjs.push_back( &obj) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrids1d::addList( ObjData& obj)
|
||||
{
|
||||
// Se abilitato e superata la soglia ...
|
||||
if ( m_bActivate && m_nonGridObjs.size() == gridActivationThreshold) {
|
||||
if ( gridActivationThreshold > 0) {
|
||||
|
||||
// all objs stored in 'm_nonGridObjs' are inserted in grids
|
||||
for ( size_t i = 0; i < gridActivationThreshold; ++i ) {
|
||||
addGrid( *m_nonGridObjs[i] );
|
||||
}
|
||||
|
||||
// ... the 'm_nonGridObjs' vector is cleared ...
|
||||
m_nonGridObjs.clear() ;
|
||||
}
|
||||
|
||||
addGrid( obj) ;
|
||||
|
||||
// ... and the usage of the hierarchical hash grids is activated irrevocably.
|
||||
m_bGridActive = true ;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
// The body is marked as being added to 'm_nonGridObjs' by setting the grid pointer to nullptr and
|
||||
// setting the cell-ID to '1'. Additionally, the hash value is used to memorize the body's index
|
||||
// position in the 'm_nonGridObjs' vector.
|
||||
obj.pHGrid = nullptr ;
|
||||
obj.nHash = m_nonGridObjs.size() ;
|
||||
obj.nCellId = 1 ;
|
||||
m_nonGridObjs.push_back( &obj) ;
|
||||
}
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "DllMain.h"
|
||||
#include "/EgtDev/Include/EGkHashGrids2d.h"
|
||||
#include "/EgtDev/Include/EgnStringUtils.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
+1
-2
@@ -15,7 +15,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "DllMain.h"
|
||||
#include "/EgtDev/Include/EGkHashGrids3d.h"
|
||||
#include "/EgtDev/Include/EgnStringUtils.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
@@ -684,7 +684,6 @@ HashGrids3d::Update( void)
|
||||
double dSize = 0 ;
|
||||
Obj.box.GetDiameter( dSize) ;
|
||||
double dCellSpan = pGrid->GetCellSpan() ;
|
||||
|
||||
if ( dSize >= dCellSpan || dSize < ( dCellSpan / hierarchyFactor)) {
|
||||
pGrid->Remove( Obj) ;
|
||||
addGrid( Obj) ;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "IntersCrvCompoCrvCompo.h"
|
||||
#include "CurveAux.h"
|
||||
#include "/EgtDev/Include/EgkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkAngle.h"
|
||||
#include "/EgtDev/Include/EGkHashGrids2d.h"
|
||||
#include <algorithm>
|
||||
@@ -541,7 +541,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||
// se il tipo di accostamento per la curva A non è definito
|
||||
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
||||
if ( i > 0 || bCrvAClosed) {
|
||||
if ( i > 0 || ( bCrvAClosed && ! bAutoInters)) {
|
||||
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
|
||||
m_Info[i].IciA[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciA[1].nNextTy : m_Info[j].IciA[0].nNextTy) ;
|
||||
}
|
||||
@@ -549,7 +549,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
// se il tipo di allontanamento per la curva A non è definito
|
||||
int ki = ( m_Info[i].bOverlap ? 1 : 0) ;
|
||||
if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
||||
if ( i < m_nNumInters - 1 || bCrvAClosed) {
|
||||
if ( i < m_nNumInters - 1 || ( bCrvAClosed && ! bAutoInters)) {
|
||||
int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ;
|
||||
m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[0].nPrevTy ;
|
||||
}
|
||||
@@ -561,14 +561,14 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||
// se il tipo di accostamento per la curva B non è definito
|
||||
if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) {
|
||||
if ( i > 0 || bCrvBClosed) {
|
||||
if ( i > 0 || ( bCrvBClosed && ! bAutoInters)) {
|
||||
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
|
||||
m_Info[i].IciB[0].nPrevTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ;
|
||||
}
|
||||
}
|
||||
// se il tipo di allontanamento per la curva B non è definito
|
||||
if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) {
|
||||
if ( i < m_nNumInters - 1 || bCrvBClosed) {
|
||||
if ( i < m_nNumInters - 1 || ( bCrvBClosed && ! bAutoInters)) {
|
||||
int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ;
|
||||
m_Info[i].IciB[0].nNextTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nPrevTy : m_Info[j].IciB[0].nPrevTy) ;
|
||||
}
|
||||
@@ -702,9 +702,9 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
// assegno sottoindici (considero solo intersezioni overlap)
|
||||
int ki = 0 ;
|
||||
int kj = 1 ;
|
||||
// verifico se entrambe overlap, la precedente termina con ON e la successiva inizia con ON
|
||||
// verifico se entrambe overlap con lo stesso verso, la precedente termina con ON e la successiva inizia con ON
|
||||
// sia sulla curva A sia sulla curva B (tenendo conto del senso equiverso/controverso)
|
||||
if ( m_Info[j].bOverlap && m_Info[i].bOverlap &&
|
||||
if ( m_Info[j].bOverlap && m_Info[i].bOverlap && m_Info[j].bCBOverEq == m_Info[i].bCBOverEq &&
|
||||
m_Info[j].IciA[kj].nNextTy == ICCT_ON && m_Info[i].IciA[ki].nPrevTy == ICCT_ON &&
|
||||
GetCrvBDirANext( m_Info[j]) == ICCT_ON && GetCrvBDirAPrev( m_Info[i]) == ICCT_ON) {
|
||||
// CurvaA : riporto il secondo punto del successivo sul secondo punto del precedente
|
||||
|
||||
+12
-13
@@ -23,7 +23,7 @@
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||
#include "/EgtDev/Include/EGtPointerOwner.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
@@ -391,7 +391,7 @@ IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
|
||||
IntersCurveCurve::GetCurveClassification( int nCrv, double dLenMin, CRVCVECTOR& ccClass)
|
||||
{
|
||||
// pulisco vettore classificazioni
|
||||
ccClass.clear() ;
|
||||
@@ -407,7 +407,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
|
||||
return false ;
|
||||
// se esiste almeno una intersezione
|
||||
if ( m_nIntersCount >= 1)
|
||||
return CalcCurveClassification( m_pCurve[0], m_Info, ccClass) ;
|
||||
return CalcCurveClassification( m_pCurve[0], m_Info, dLenMin, ccClass) ;
|
||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||
else
|
||||
return CalcCurveInOrOut( m_pCurve[0], m_pCurve[1], ccClass) ;
|
||||
@@ -424,7 +424,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
|
||||
SwapInfoAB( InfoTmp, 1) ;
|
||||
// se esiste almeno una intersezione
|
||||
if ( m_nIntersCount >= 1)
|
||||
return CalcCurveClassification( m_pCurve[1], InfoTmp, ccClass) ;
|
||||
return CalcCurveClassification( m_pCurve[1], InfoTmp, dLenMin, ccClass) ;
|
||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||
else
|
||||
return CalcCurveInOrOut( m_pCurve[1], m_pCurve[0], ccClass) ;
|
||||
@@ -461,7 +461,7 @@ IntersCurveCurve::SwapInfoAB( ICCIVECTOR& Info, int IndCrvOrd)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTOR& Info, CRVCVECTOR& ccClass)
|
||||
IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTOR& Info, double dLenMin, CRVCVECTOR& ccClass)
|
||||
{
|
||||
// numero intersezioni
|
||||
int nNumInters = int( Info.size()) ;
|
||||
@@ -471,6 +471,8 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
||||
double dStartPar, dEndPar ;
|
||||
if ( pCurve == nullptr || ! pCurve->GetDomain( dStartPar, dEndPar))
|
||||
return false ;
|
||||
// limito lunghezza minima
|
||||
dLenMin = max( dLenMin, EPS_ZERO) ;
|
||||
// elimino intersezioni senza attraversamento che giacciono in intervalli di sovrapposizione
|
||||
ICCIVECTOR InfoCorr ;
|
||||
InfoCorr.reserve( Info.size()) ;
|
||||
@@ -527,7 +529,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
||||
for ( int i = 0 ; i < nNumInters ; ++ i) {
|
||||
// se è definito un tratto precedente
|
||||
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ;
|
||||
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > EPS_SMALL) {
|
||||
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
|
||||
// verifico che la definizione sul tratto sia omogenea e valida
|
||||
int nPrevTy = InfoCorr[i].IciA[0].nPrevTy ;
|
||||
if ( ( nLastTy != ICCT_NULL && nPrevTy != nLastTy) ||
|
||||
@@ -562,7 +564,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
||||
}
|
||||
}
|
||||
// eventuale tratto finale rimasto
|
||||
if ( dCurrPar < dEndPar - EPS_PARAM && dEndLen - dCurrLen > EPS_SMALL) {
|
||||
if ( dCurrPar < dEndPar - EPS_PARAM && dEndLen - dCurrLen > dLenMin) {
|
||||
// verifico che la definizione sul tratto sia valida
|
||||
if ( nLastTy == ICCT_NULL || nLastTy == ICCT_ON)
|
||||
return false ;
|
||||
@@ -657,11 +659,8 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
|
||||
bool
|
||||
IntersCurveCurve::GetCurveOutClass( const ICurve* pCurve, int& nClass)
|
||||
{
|
||||
PolyLine PL ;
|
||||
if ( ! pCurve->ApproxWithLines( LIN_TOL_APPROX, ANG_TOL_APPROX_DEG, ICurve::APL_SPECIAL, PL))
|
||||
return false ;
|
||||
double dArea ;
|
||||
if ( ! PL.GetAreaXY( dArea))
|
||||
if ( ! pCurve->GetAreaXY( dArea))
|
||||
return false ;
|
||||
nClass = (( dArea > 0) ? CRVC_OUT : CRVC_IN) ;
|
||||
return true ;
|
||||
@@ -673,7 +672,7 @@ IntersCurveCurve::GetRegionCurveClassification( void)
|
||||
{
|
||||
// classifico la prima curva rispetto alla seconda
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ! GetCurveClassification( 0, ccClass))
|
||||
if ( ! GetCurveClassification( 0, EPS_SMALL, ccClass))
|
||||
return CCREGC_NULL ;
|
||||
// derivo la classificazione delle curve come regioni
|
||||
bool bIn = false ;
|
||||
@@ -710,7 +709,7 @@ IntersCurveCurve::GetRegionCurveClassification( void)
|
||||
if ( bOnP)
|
||||
return CCREGC_IN2 ;
|
||||
CRVCVECTOR ccClass2 ;
|
||||
if ( ! GetCurveClassification( 1, ccClass2) || ccClass2.empty())
|
||||
if ( ! GetCurveClassification( 1, EPS_SMALL, ccClass2) || ccClass2.empty())
|
||||
return CCREGC_NULL ;
|
||||
if ( ccClass2[0].nClass == CRVC_OUT)
|
||||
return CCREGC_OUT ;
|
||||
|
||||
+127
-108
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
// EgalTech 2020-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineBox.cpp Data : 07.05.20 Versione : 2.2e1
|
||||
// File : IntersLineBox.cpp Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Implementazione della intersezione linea/box.
|
||||
//
|
||||
//
|
||||
@@ -13,13 +13,77 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e box allineato assi devono essere nel medesimo sistema di riferimento.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptMin, const Point3d& ptMax,
|
||||
double& dU1, double& dU2)
|
||||
{
|
||||
// Verifico il versore
|
||||
if ( vtL.IsSmall())
|
||||
return false ;
|
||||
|
||||
// Verifico gli estremi del box
|
||||
if ( ptMin.x > ptMax.x + EPS_SMALL ||
|
||||
ptMin.y > ptMax.y + EPS_SMALL ||
|
||||
ptMin.z > ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// Casi di intersezione impossibile
|
||||
if ( abs( vtL.x) < EPS_ZERO && ( ptL.x < ptMin.x - EPS_SMALL || ptL.x > ptMax.x + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtL.y) < EPS_ZERO && ( ptL.y < ptMin.y - EPS_SMALL || ptL.y > ptMax.y + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtL.z) < EPS_ZERO && ( ptL.z < ptMin.z - EPS_SMALL || ptL.z > ptMax.z + EPS_SMALL))
|
||||
return false ;
|
||||
|
||||
// Parametri degli estremi della retta
|
||||
dU1 = -INFINITO ;
|
||||
dU2 = INFINITO ;
|
||||
|
||||
// Confronto con piani YZ (perpendicolari ad asse X)
|
||||
if ( vtL.x > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.x - ptL.x) / vtL.x) ;
|
||||
dU2 = min( dU2, ( ptMax.x - ptL.x) / vtL.x) ;
|
||||
}
|
||||
else if ( vtL.x < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.x - ptL.x) / vtL.x) ;
|
||||
dU2 = min( dU2, ( ptMin.x - ptL.x) / vtL.x) ;
|
||||
}
|
||||
|
||||
// Confronto con piani ZX (perpendicolari ad asse Y)
|
||||
if ( vtL.y > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.y - ptL.y) / vtL.y) ;
|
||||
dU2 = min( dU2, ( ptMax.y - ptL.y) / vtL.y) ;
|
||||
}
|
||||
else if ( vtL.y < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.y - ptL.y) / vtL.y) ;
|
||||
dU2 = min( dU2, ( ptMin.y - ptL.y) / vtL.y) ;
|
||||
}
|
||||
|
||||
// Confronto con piani XY (perpendicolari ad asse Z)
|
||||
if ( vtL.z > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.z - ptL.z) / vtL.z) ;
|
||||
dU2 = min( dU2, ( ptMax.z - ptL.z) / vtL.z) ;
|
||||
}
|
||||
else if ( vtL.z < -EPS_ZERO){
|
||||
dU1 = max( dU1, ( ptMax.z - ptL.z) / vtL.z) ;
|
||||
dU2 = min( dU2, ( ptMin.z - ptL.z) / vtL.z) ;
|
||||
}
|
||||
|
||||
return ( dU2 >= dU1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL1, const Point3d& ptL2, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite)
|
||||
@@ -38,114 +102,69 @@ bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite)
|
||||
{
|
||||
// Recupero i dati del Box
|
||||
Point3d ptMin ;
|
||||
double dDimX, dDimY, dDimZ ;
|
||||
if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimZ))
|
||||
Point3d ptMin, ptMax ;
|
||||
if ( ! b3Box.GetMinMax( ptMin, ptMax))
|
||||
return false ;
|
||||
// Contorno di base
|
||||
PolyLine PL ;
|
||||
PL.AddUPoint( 0, ptMin) ;
|
||||
PL.AddUPoint( 1, ptMin + Vector3d( dDimX, 0, 0)) ;
|
||||
PL.AddUPoint( 2, ptMin + Vector3d( dDimX, dDimY, 0)) ;
|
||||
PL.AddUPoint( 3, ptMin + Vector3d( 0, dDimY, 0)) ;
|
||||
PL.Close() ;
|
||||
// Vettore altezza
|
||||
Vector3d vtExtr( 0, 0, dDimZ) ;
|
||||
// Creo la superficie trimesh equivalente
|
||||
SurfTriMesh Stm ;
|
||||
if ( ! Stm.CreateByExtrusion( PL, vtExtr))
|
||||
return false ;
|
||||
SurfTriMesh StmBot ;
|
||||
if ( ! StmBot.CreateByFlatContour( PL))
|
||||
return false ;
|
||||
StmBot.Invert() ;
|
||||
SurfTriMesh StmTop ;
|
||||
if ( ! StmTop.CreateByFlatContour( PL))
|
||||
return false ;
|
||||
StmTop.Translate( vtExtr) ;
|
||||
if ( ! Stm.DoSewing( StmBot) || ! Stm.DoSewing( StmTop))
|
||||
return false ;
|
||||
// Calcolo l'intersezione
|
||||
ILSIVECTOR vInfo ;
|
||||
if ( ! IntersLineSurfTm( ptL, vtL, dLen, Stm, vInfo, bFinite))
|
||||
return false ;
|
||||
// ciclo sulle intersezioni
|
||||
double dUcurr = -INFINITO ;
|
||||
for ( const auto& Info : vInfo) {
|
||||
// se intersezione puntuale
|
||||
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||
int nFlag = ILBT_TOUCH ;
|
||||
if ( Info.dCosDN > EPS_ZERO)
|
||||
nFlag = ILBT_OUT ;
|
||||
else if ( Info.dCosDN < -EPS_ZERO)
|
||||
nFlag = ILBT_IN ;
|
||||
vInters.emplace_back( nFlag, Info.dU) ;
|
||||
dUcurr = Info.dU ;
|
||||
|
||||
// Pulisco vettore intersezioni
|
||||
vInters.clear() ;
|
||||
|
||||
// Eseguo intersezione della linea completa
|
||||
double dU1, dU2 ;
|
||||
bool bInters = IntersLineBox( ptL, vtL, b3Box.GetMin(), b3Box.GetMax(), dU1, dU2) ;
|
||||
|
||||
// Se non c'è intersezione
|
||||
if ( ! bInters || ( bFinite && ( dU1 > dLen + EPS_SMALL || dU2 < -EPS_SMALL)))
|
||||
return true ;
|
||||
|
||||
// Se le due intersezioni coincidono
|
||||
if ( ( dU2 - dU1) < EPS_SMALL) {
|
||||
double dU = ( dU1 + dU2) / 2 ;
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_TOUCH, dU) ;
|
||||
}
|
||||
// se altrimenti intersezione con coincidenza
|
||||
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
||||
if ( Info.dU > dUcurr - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_TG_INI, Info.dU) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, Info.dU2) ;
|
||||
dUcurr = Info.dU2 ;
|
||||
else {
|
||||
if ( dU > - EPS_SMALL && dU < dLen + EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_TOUCH, Clamp( dU, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
// elimino intersezioni ripetute
|
||||
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||
// intersezione precedente
|
||||
size_t i = j - 1 ;
|
||||
// se sono dello stesso tipo, elimino una delle due
|
||||
if ( vInters[i].first == vInters[j].first) {
|
||||
// se entranti elimino la prima
|
||||
if ( vInters[i].first == ILBT_IN || vInters[i].first == ILBT_TG_INI)
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
// altrimenti la seconda
|
||||
else
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se hanno lo stesso parametro
|
||||
else if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
||||
// se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
|
||||
if ( ( vInters[i].first == ILBT_IN && vInters[j].first == ILBT_OUT) ||
|
||||
( vInters[i].first == ILBT_OUT && vInters[j].first == ILBT_IN)) {
|
||||
vInters[i].first = ILBT_TOUCH ;
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se prima puntuale e l'altra inizio o fine di coincidenza, elimino la prima
|
||||
else if ( ( vInters[i].first == ILBT_IN || vInters[i].first == ILBT_OUT || vInters[i].first == ILBT_TOUCH) &&
|
||||
( vInters[j].first == ILBT_TG_INI || vInters[j].first == ILBT_TG_FIN)) {
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se prima inizio o fine di coincidenza e l'altra puntuale, elimino la seconda
|
||||
else if ( ( vInters[i].first == ILBT_TG_INI || vInters[i].first == ILBT_TG_FIN) &&
|
||||
( vInters[j].first == ILBT_IN || vInters[j].first == ILBT_OUT || vInters[j].first == ILBT_TOUCH)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
|
||||
else if ( ( vInters[i].first == ILBT_TG_FIN && vInters[j].first == ILBT_TG_INI) ||
|
||||
( vInters[i].first == ILBT_TG_INI && vInters[j].first == ILBT_TG_FIN)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
// passo alla successiva
|
||||
++ j ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Se sono due intersezioni con la linea giacente su una faccia del box
|
||||
if ( ( abs( vtL.x) < EPS_ZERO && ( abs( ptL.x - ptMin.x) < EPS_SMALL || abs( ptL.x - ptMax.x) < EPS_SMALL)) ||
|
||||
( abs( vtL.y) < EPS_ZERO && ( abs( ptL.y - ptMin.y) < EPS_SMALL || abs( ptL.y - ptMax.y) < EPS_SMALL)) ||
|
||||
( abs( vtL.z) < EPS_ZERO && ( abs( ptL.z - ptMin.z) < EPS_SMALL || abs( ptL.z - ptMax.z) < EPS_SMALL))) {
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_TG_INI, dU1) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, dU2) ;
|
||||
}
|
||||
else {
|
||||
if ( dU1 > dLen - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_IN, dLen) ;
|
||||
else if ( dU2 < EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||
else {
|
||||
vInters.emplace_back( ILBT_TG_INI, Clamp( dU1, 0., dLen)) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, Clamp( dU2, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Altrimenti sono due intersezioni con attraversamento
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_IN, dU1) ;
|
||||
vInters.emplace_back( ILBT_OUT, dU2) ;
|
||||
}
|
||||
else {
|
||||
if ( dU1 > dLen - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_IN, dLen) ;
|
||||
else if ( dU2 < EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||
else {
|
||||
vInters.emplace_back( ILBT_IN, Clamp( dU1, 0., dLen)) ;
|
||||
vInters.emplace_back( ILBT_OUT, Clamp( dU2, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2022-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineBox.h Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Dichiarazione delle funzioni base per intersezione linea/box.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 08.01.22 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e box allineato agli assi sono nel medesimo riferimento.
|
||||
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptMin, const Point3d& ptMax,
|
||||
double& dU1, double& dU2) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
TestIntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptMin, const Point3d& ptMax)
|
||||
{
|
||||
double dU1, dU2 ;
|
||||
return IntersLineBox( ptL, vtL, ptMin, ptMax, dU1, dU2) ;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineCaps.cpp Data : 22.05.23 Versione : 2.5e3
|
||||
// Contenuto : Implementazione della intersezione linea/capsule.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 22.05.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "IntersLineCaps.h"
|
||||
#include "DistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSphere.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e capsule sono nel medesimo riferimento.
|
||||
// Il capsule è definito con centri delle due estremità, e raggio.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineCaps( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptCaps1, const Point3d& ptCaps2, double dRad,
|
||||
double& dU1, double& dU2)
|
||||
{
|
||||
// Determino versore e lunghezza asse Capsule
|
||||
Vector3d vtCaps = ptCaps2 - ptCaps1 ;
|
||||
double dLen = vtCaps.Len() ;
|
||||
if ( dLen < EPS_SMALL) {
|
||||
Point3d ptInt1, ptInt2 ;
|
||||
if ( IntersLineSphere( ptL, vtL, Media( ptCaps1, ptCaps2), dRad, ptInt1, ptInt2) != ILST_SEC)
|
||||
return false ;
|
||||
dU1 = ( ptInt1 - ptL) * vtL ;
|
||||
dU2 = ( ptInt2 - ptL) * vtL ;
|
||||
return true ;
|
||||
}
|
||||
vtCaps /= dLen ;
|
||||
// Distanza tra la linea e il segmento asse del capsule
|
||||
DistLineLine dstLL( ptL, vtL, 1, ptCaps1, vtCaps, dLen, false, true) ;
|
||||
double dSqDist ;
|
||||
if ( dstLL.GetSqDist( dSqDist) && dSqDist >= dRad * dRad)
|
||||
return false ;
|
||||
// Calcolo i punti di intersezione
|
||||
Point3d ptRef, ptTmp ;
|
||||
dstLL.GetMinDistPoints( ptRef, ptTmp) ;
|
||||
double dSqDelta = dRad * dRad - dSqDist ;
|
||||
double dDist = sqrt( dSqDelta) ;
|
||||
dU1 = ( ptRef - ptL) * vtL - dDist ;
|
||||
dU2 = dU1 + 2 * dDist ;
|
||||
return true ;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineCaps.h Data : 22.05.23 Versione : 2.5e4
|
||||
// Contenuto : Dichiarazione funzioni base per intersezione linea/capsule.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 22.05.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e capsule sono nel medesimo riferimento.
|
||||
// Il capsule è definito con centri delle due estremità, e raggio.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool IntersLineCaps( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptCaps1, const Point3d& ptCaps2, double dRad,
|
||||
double& dU1, double& dU2) ;
|
||||
@@ -0,0 +1,138 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineCone.cpp Data : 16.05.23 Versione : 2.5e3
|
||||
// Contenuto : Implementazione della intersezione linea/tronco di cono.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 16.05.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "IntersLineCone.h"
|
||||
#include "IntersLineCyl.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e tronco di cono sono nel medesimo riferimento.
|
||||
// Il tronco di cono è centrato sull'asse Z e appoggiato con RMin sul piano XY.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineCone( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRadMin, double dRadMax, double dHeight,
|
||||
double& dU1, double& dU2)
|
||||
{
|
||||
// Verifico il versore
|
||||
if ( vtL.IsSmall())
|
||||
return false ;
|
||||
|
||||
// Verifico il tronco di cono
|
||||
if ( ( dRadMin < EPS_SMALL && dRadMax < EPS_SMALL) || dHeight < EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// Se è un cilindro, rimando a questo
|
||||
if ( abs( dRadMax - dRadMin) < EPS_SMALL)
|
||||
return IntersLineCyl( ptL, vtL, ( dRadMin + dRadMax) / 2, dHeight, dU1, dU2) ;
|
||||
|
||||
// Se raggi invertiti, li scambio
|
||||
if ( dRadMin > dRadMax)
|
||||
swap( dRadMin, dRadMax) ;
|
||||
|
||||
// Tangente dell'angolo di semi-apertura del cono
|
||||
double dTanTheta = ( dRadMax - dRadMin) / dHeight ;
|
||||
double dSqTanTheta = dTanTheta * dTanTheta ;
|
||||
double dSqCosTheta = 1 / ( 1 + dSqTanTheta) ;
|
||||
|
||||
// Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non giace sul cono)
|
||||
int nBasInt = 0 ;
|
||||
if ( abs( vtL.z) > EPS_ZERO) {
|
||||
// le linee tangenti al cono non sono considerate intersecanti
|
||||
bool bSameHAng = ( abs( abs( vtL.x) - abs( vtL.y)) < EPS_SMALL && abs( dSqCosTheta - vtL.z * vtL.z) < 2 * abs( vtL.z) * EPS_SMALL) ;
|
||||
double EpsRad = ( bSameHAng ? - EPS_SMALL : EPS_SMALL) ;
|
||||
Point3d ptInt1 = ptL + ( ( 0 - ptL.z) / vtL.z) * vtL ;
|
||||
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRadMin * dRadMin + 2 * dRadMin * EpsRad) {
|
||||
dU1 = ( ptInt1 - ptL) * vtL ;
|
||||
nBasInt += 1 ;
|
||||
}
|
||||
Point3d ptInt2 = ptL + ( ( dHeight - ptL.z) / vtL.z) * vtL ;
|
||||
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRadMax * dRadMax + 2 * dRadMax * EpsRad) {
|
||||
dU2 = ( ptInt2 - ptL) * vtL ;
|
||||
nBasInt += 2 ;
|
||||
}
|
||||
}
|
||||
|
||||
// Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
|
||||
if ( nBasInt == 3) {
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Posizione del vertice del cono
|
||||
double dDeltaH = ( dRadMin < EPS_SMALL ? 0 : dRadMin / dTanTheta) ;
|
||||
// Sposto il punto di passaggio della linea di conseguenza
|
||||
Point3d ptMyL = ptL + Z_AX * dDeltaH ;
|
||||
|
||||
// Determino le intersezioni con la superficie laterale del cono
|
||||
DBLVECTOR vdCoeff{ ptMyL.x * ptMyL.x + ptMyL.y * ptMyL.y - ptMyL.z * ptMyL.z * dSqTanTheta,
|
||||
2 * ( ptMyL.x * vtL.x + ptMyL.y * vtL.y - ptMyL.z * vtL.z * dSqTanTheta),
|
||||
vtL.x * vtL.x + vtL.y * vtL.y - vtL.z * vtL.z * dSqTanTheta} ;
|
||||
DBLVECTOR vdRoots ;
|
||||
int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
|
||||
|
||||
// Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del tronco di cono
|
||||
if ( nRoot == 2) {
|
||||
double dIntZ2 = ptL.z + vdRoots[1] * vtL.z ;
|
||||
if ( dIntZ2 < 0 - EPS_SMALL || dIntZ2 > dHeight + EPS_SMALL)
|
||||
-- nRoot ;
|
||||
}
|
||||
if ( nRoot >= 1) {
|
||||
double dIntZ1 = ptL.z + vdRoots[0] * vtL.z ;
|
||||
if ( dIntZ1 < 0 - EPS_SMALL || dIntZ1 > dHeight + EPS_SMALL) {
|
||||
if ( nRoot == 2)
|
||||
vdRoots[0] = vdRoots[1] ;
|
||||
-- nRoot ;
|
||||
}
|
||||
}
|
||||
|
||||
// Due soluzioni: la retta interseca due volte la superficie laterale
|
||||
if ( nRoot == 2) {
|
||||
dU1 = vdRoots[0] ;
|
||||
dU2 = vdRoots[1] ;
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Una soluzione : la retta interseca la superficie laterale e un piano
|
||||
else if ( nRoot == 1) {
|
||||
// Se piano superiore
|
||||
if ( nBasInt == 2) {
|
||||
dU1 = vdRoots[0] ;
|
||||
}
|
||||
// altrimenti piano inferiore
|
||||
else if ( nBasInt == 1) {
|
||||
dU2 = vdRoots[0] ;
|
||||
}
|
||||
// altrimenti niente
|
||||
else
|
||||
return false ;
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Nessuna soluzione : nessuna intersezione
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineCone.h Data : 16.05.23 Versione : 2.5e3
|
||||
// Contenuto : Dichiarazione funzioni base per intersezione linea/cono tronco.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 16.05.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e tronco di cono sono nel medesimo riferimento.
|
||||
// Il tronco di cono è centrato sull'asse Z e appoggiato con RMin sul piano XY.
|
||||
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineCone( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRadMin, double dRadMax, double dHeight,
|
||||
double& dU1, double& dU2) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
TestIntersLineCone( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRadMin, double dRadMax, double dHeight)
|
||||
{
|
||||
double dU1, dU2 ;
|
||||
return IntersLineCone( ptL, vtL, dRadMin, dRadMax, dHeight, dU1, dU2) ;
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineCyl.cpp Data : 16.05.23 Versione : 2.5e3
|
||||
// Contenuto : Implementazione della intersezione linea/cilindro.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 16.05.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "IntersLineCyl.h"
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e cilindro sono nel medesimo riferimento.
|
||||
// Il cilindro è centrato sull'asse Z e appoggiato sul piano XY.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRad, double dHeight,
|
||||
double& dU1, double& dU2)
|
||||
{
|
||||
// Verifico il versore
|
||||
if ( vtL.IsSmall())
|
||||
return false ;
|
||||
|
||||
// Verifico il cilindro
|
||||
if ( dRad < EPS_SMALL || dHeight < EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non parallela ad esse)
|
||||
int nBasInt = 0 ;
|
||||
if ( abs( vtL.z) > EPS_ZERO) {
|
||||
// le linee tangenti al cilindro non sono considerate intersecanti
|
||||
double EpsRad = ( vtL.IsZeroXY() ? - EPS_SMALL : EPS_SMALL) ;
|
||||
Point3d ptInt1 = ptL + ( ( 0 - ptL.z) / vtL.z) * vtL ;
|
||||
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRad * dRad + 2 * dRad * EpsRad) {
|
||||
dU1 = ( ptInt1 - ptL) * vtL ;
|
||||
nBasInt += 1 ;
|
||||
}
|
||||
Point3d ptInt2 = ptL + ( ( dHeight - ptL.z) / vtL.z) * vtL ;
|
||||
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRad * dRad + 2 * dRad * EpsRad) {
|
||||
dU2 = ( ptInt2 - ptL) * vtL ;
|
||||
nBasInt += 2 ;
|
||||
}
|
||||
}
|
||||
|
||||
// Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
|
||||
if ( nBasInt == 3) {
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Determino le intersezioni con la superficie laterale del cilindro
|
||||
DBLVECTOR vdCoeff{ ptL.x * ptL.x + ptL.y * ptL.y - dRad * dRad,
|
||||
2 * ( ptL.x * vtL.x + ptL.y * vtL.y),
|
||||
vtL.x * vtL.x + vtL.y * vtL.y} ;
|
||||
DBLVECTOR vdRoots ;
|
||||
int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
|
||||
|
||||
// Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del cilindro
|
||||
if ( nRoot == 2) {
|
||||
double dIntZ2 = ptL.z + vdRoots[1] * vtL.z ;
|
||||
if ( dIntZ2 < 0 - EPS_SMALL || dIntZ2 > dHeight + EPS_SMALL)
|
||||
-- nRoot ;
|
||||
}
|
||||
if ( nRoot >= 1) {
|
||||
double dIntZ1 = ptL.z + vdRoots[0] * vtL.z ;
|
||||
if ( dIntZ1 < 0 - EPS_SMALL || dIntZ1 > dHeight + EPS_SMALL) {
|
||||
if ( nRoot == 2)
|
||||
vdRoots[0] = vdRoots[1] ;
|
||||
-- nRoot ;
|
||||
}
|
||||
}
|
||||
|
||||
// Due soluzioni: la retta interseca due volte la superficie laterale
|
||||
if ( nRoot == 2) {
|
||||
dU1 = vdRoots[0] ;
|
||||
dU2 = vdRoots[1] ;
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Una soluzione : la retta interseca la superficie laterale e un piano
|
||||
else if ( nRoot == 1) {
|
||||
// Se piano superiore
|
||||
if ( nBasInt == 2) {
|
||||
dU1 = vdRoots[0] ;
|
||||
}
|
||||
// altrimenti piano inferiore
|
||||
else if ( nBasInt == 1) {
|
||||
dU2 = vdRoots[0] ;
|
||||
}
|
||||
// altrimenti niente
|
||||
else
|
||||
return false ;
|
||||
if ( dU1 > dU2)
|
||||
swap( dU1, dU2) ;
|
||||
// Trovate intersezioni
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Nessuna soluzione : nessuna intersezione
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e cilindro sono nel medesimo riferimento.
|
||||
// Il cilindro è definito con centro della base, asse, raggio e altezza.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptCyl, const Vector3d& vtCyl, double dRad, double dHeight,
|
||||
double& dU1, double& dU2)
|
||||
{
|
||||
// Riferimento intrinseco del cilindro
|
||||
Frame3d frCyl ;
|
||||
if ( ! frCyl.Set( ptCyl, vtCyl))
|
||||
return false ;
|
||||
// Ora eseguo i conti nel riferimento intrinseco
|
||||
return IntersLineCyl( GetToLoc( ptL, frCyl), GetToLoc( vtL, frCyl), dRad, dHeight, dU1, dU2) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e cilindro sono nel medesimo riferimento.
|
||||
// Il cilindro è definito con centri delle due basi, e raggio.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptCyl1, const Point3d& ptCyl2, double dRad,
|
||||
double& dU1, double& dU2)
|
||||
{
|
||||
// Determino asse ed altezza del cilindro
|
||||
Vector3d vtCyl = ptCyl2 - ptCyl1 ;
|
||||
double dHeight = vtCyl.Len() ;
|
||||
if ( dHeight < EPS_SMALL)
|
||||
return false ;
|
||||
vtCyl /= dHeight ;
|
||||
// Riferimento intrinseco del cilindro
|
||||
Frame3d frCyl ;
|
||||
if ( ! frCyl.Set( ptCyl1, vtCyl))
|
||||
return false ;
|
||||
// Ora eseguo i conti nel riferimento intrinseco
|
||||
return IntersLineCyl( GetToLoc( ptL, frCyl), GetToLoc( vtL, frCyl), dRad, dHeight, dU1, dU2) ;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineCyl.h Data : 16.05.23 Versione : 2.5e3
|
||||
// Contenuto : Dichiarazione funzioni base per intersezione linea/cilindro.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 16.05.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e cilindro sono nel medesimo riferimento.
|
||||
// Il cilindro è centrato sull'asse Z e appoggiato sul piano XY.
|
||||
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRad, double dHeight,
|
||||
double& dU1, double& dU2) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
TestIntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||
double dRad, double dHeight)
|
||||
{
|
||||
double dU1, dU2 ;
|
||||
return IntersLineCyl( ptL, vtL, dRad, dHeight, dU1, dU2) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e cilindro sono nel medesimo riferimento.
|
||||
// Il cilindro è definito con centro della base, asse raggio e altezza.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptCyl, const Vector3d& vtCyl, double dRad, double dHeight,
|
||||
double& dU1, double& dU2) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e cilindro sono nel medesimo riferimento.
|
||||
// Il cilindro è definito con centri delle due basi, e raggio.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptCyl1, const Point3d& ptCyl2, double dRad,
|
||||
double& dU1, double& dU2) ;
|
||||
+1
-1
@@ -66,7 +66,7 @@ IntersLineLine::IntersInfiniteLines( const ICurveLine& Line1, const ICurveLine&
|
||||
double dLen1XY = vtDir1.LenXY() ;
|
||||
if ( dLen1XY < EPS_SMALL)
|
||||
return ;
|
||||
// linea 2 : Start, Direzione e Lunghezza
|
||||
// linea 2 : Start, End, Direzione e Lunghezza
|
||||
Point3d ptS2 = Line2.GetStart() ;
|
||||
Point3d ptE2 = Line2.GetEnd() ;
|
||||
Vector3d vtDir2 = ptE2 - ptS2 ;
|
||||
|
||||
+13
-8
@@ -26,20 +26,25 @@ IntersLineSphere( const Point3d& ptL, const Vector3d& vtL, const Point3d& ptCen,
|
||||
return ILST_NO ;
|
||||
// Proiezione del centro della sfera sulla linea
|
||||
Point3d ptP = ptL + (( ptCen - ptL) * vtL) * vtL ;
|
||||
// Distanza di questo punto di proiezione dal centro della sfera
|
||||
double dDist = Dist( ptCen, ptP) ;
|
||||
// Quadrato della distanza di questo punto di proiezione dal centro della sfera
|
||||
double dSqDist = SqDist( ptCen, ptP) ;
|
||||
// Differenza tra quadrato del raggio e quadrato della distanza
|
||||
double dSqDelta = dRad * dRad - dSqDist ;
|
||||
|
||||
// Se distanza superiore al raggio, nessuna intersezione
|
||||
if ( dSqDelta < - 2 * dRad * EPS_SMALL)
|
||||
return ILST_NO ;
|
||||
|
||||
// Se distanza uguale al raggio, intersezione tangente
|
||||
if ( abs( dDist - dRad) < EPS_SMALL) {
|
||||
if ( dSqDelta < EPS_SMALL * EPS_SMALL) {
|
||||
ptI1 = ptP ;
|
||||
ptI2 = ptP ;
|
||||
return ILST_TG ;
|
||||
}
|
||||
// Se distanza superiore al raggio, nessuna intersezione
|
||||
if ( dDist > dRad)
|
||||
return ILST_NO ;
|
||||
|
||||
// Distanza inferiore al raggio, due intersezioni secanti
|
||||
double dDist2 = sqrt( dRad * dRad - dDist * dDist) ;
|
||||
double dDist2 = sqrt( dSqDelta) ;
|
||||
ptI1 = ptP - dDist2 * vtL ;
|
||||
ptI2 = ptP + dDist2 * vtL ;
|
||||
return ILST_SEC ;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-64
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2017-2018
|
||||
// EgalTech 2017-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineSurfStd.cpp Data : 03.12.18 Versione : 1.9l1
|
||||
// File : IntersLineSurfStd.cpp Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Implementazione delle funzioni di intersezione
|
||||
// componente lineare e superficie standard.
|
||||
//
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "IntersLineSurfStd.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
@@ -21,60 +22,6 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Punti e vettore devono essere espressi nel medesimo sistema di riferimento.
|
||||
// Il box è allineato con gli assi di questo sistema di riferimento.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
|
||||
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2)
|
||||
{
|
||||
// Casi di intersezione impossibile
|
||||
if ( abs( vtV.x) < EPS_ZERO && ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtV.y) < EPS_ZERO && ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtV.z) < EPS_ZERO && ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL))
|
||||
return false ;
|
||||
|
||||
// Inizializzo parametri intersezioni
|
||||
dU1 = -INFINITO ;
|
||||
dU2 = INFINITO ;
|
||||
|
||||
// Confronto con piani YZ (perpendicolari ad asse X)
|
||||
if ( vtV.x > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ;
|
||||
dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ;
|
||||
}
|
||||
else if ( vtV.x < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ;
|
||||
dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ;
|
||||
}
|
||||
|
||||
// Confronto con piani ZX (perpendicolari ad asse Y)
|
||||
if ( vtV.y > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ;
|
||||
dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ;
|
||||
}
|
||||
else if ( vtV.y < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ;
|
||||
dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ;
|
||||
}
|
||||
|
||||
// Confronto con piani XY (perpendicolari ad asse Z)
|
||||
if ( vtV.z > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ;
|
||||
dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ;
|
||||
}
|
||||
else if ( vtV.z < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ;
|
||||
dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ;
|
||||
}
|
||||
|
||||
return ( dU2 >= dU1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
LineDisc( const Point3d& ptPLine, const Vector3d& vtVLine,
|
||||
@@ -853,7 +800,7 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
|
||||
|
||||
// Parte della retta appartenente al cilindro
|
||||
if ( nIntType == CC_INF_INT) {
|
||||
dU1 = ( ptPCyl- ptPLine) * vtVLine ;
|
||||
dU1 = ( ptPCyl - ptPLine) * vtVLine ;
|
||||
// Retta e cilindro equiversi
|
||||
if ( vtVCyl * vtVLine > 0)
|
||||
dU2 = dU1 + dCylHeigth ;
|
||||
@@ -872,8 +819,7 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
|
||||
}
|
||||
// Caso di due intersezioni
|
||||
else if ( nIntType == CC_TWO_INT) {
|
||||
// Rigetto le soluzioni fuori dalla
|
||||
// regione ammissibile del cilindro.
|
||||
// Elimino le soluzioni fuori dal cilindro finito
|
||||
Point3d ptInt1 = ptPLine + dU1 * vtVLine ;
|
||||
Point3d ptInt2 = ptPLine + dU2 * vtVLine ;
|
||||
int nSolNum = 2 ;
|
||||
@@ -885,8 +831,7 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
|
||||
if ( ( ptInt2 - ptPCyl) * vtVCyl < 0 ||
|
||||
( ptInt2 - ptPCyl) * vtVCyl > dCylHeigth)
|
||||
-- nSolNum ;
|
||||
// Dal numero di soluzioni rimaste
|
||||
// aggiorno la tipologia di interferenza.
|
||||
// Aggiorno il tipo di intersezione
|
||||
if ( nSolNum == 1)
|
||||
nIntType = CC_ONE_INT_SEC ;
|
||||
else if ( nSolNum == 0)
|
||||
@@ -949,8 +894,7 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
|
||||
if ( nIntType == CC_ERROR_INT)
|
||||
return nIntType ;
|
||||
|
||||
// Parte della retta associata
|
||||
// appartiene al cilindro
|
||||
// Parte della retta associata appartiene al cilindro
|
||||
if ( nIntType == CC_INF_INT) {
|
||||
// Segmento non interferisce
|
||||
if ( dU1 > dLen + EPS_SMALL)
|
||||
@@ -978,7 +922,7 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
|
||||
if ( dU1 < - EPS_SMALL || dU1 > dLen + EPS_SMALL)
|
||||
nIntType = CC_NO_INTERS ;
|
||||
}
|
||||
// Retta associata è secante
|
||||
// Retta associata è secante con due punti di intersezione
|
||||
else if ( nIntType == CC_TWO_INT) {
|
||||
// Il segmento non interferisce
|
||||
if ( dU1 > dLen + EPS_SMALL)
|
||||
@@ -1004,6 +948,11 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
|
||||
nIntType = CC_NO_INTERS ;
|
||||
}
|
||||
}
|
||||
// Retta associata è secante con un punto di intersezione
|
||||
else if ( nIntType == CC_ONE_INT_SEC) {
|
||||
if ( dU1 < -EPS_SMALL || dU1 > dLen + EPS_SMALL)
|
||||
nIntType = CC_NO_INTERS ;
|
||||
}
|
||||
return nIntType ;
|
||||
}
|
||||
|
||||
|
||||
+4
-10
@@ -17,12 +17,11 @@
|
||||
|
||||
// In tutte le funzioni dichiarate i punti e i vettori che definiscono gli oggetti geometrici
|
||||
// devono essere espressi nel medesimo sistema di riferimento. I vettori devono essere normalizzati.
|
||||
// Il valore di ritorno è una costante intera che individua la tipologia di interferenza.
|
||||
// Il valore di ritorno è una costante intera che individua la tipologia di intersezione.
|
||||
// Se si verificano irregolarità, essa vale ERROR_INT.
|
||||
// Per riferimento vengono restituiti i parametri lungo la retta a cui avvengono le
|
||||
// intersezioni. Se non vi sono intersezioni i valori di dU1 e dU2 non hanno senso,
|
||||
// se vi è un'intersezione solo il valore di dU1 ha senso. Se vi sono più intersezioni,
|
||||
// dU1 e dU2 hanno entrambi senso.
|
||||
// intersezioni. Se non vi sono intersezioni i valori di dU1 e dU2 non sono definiti,
|
||||
// se vi è un'intersezione vale solo dU1, con due soluzioni valgono entrambi.
|
||||
// Nelle routine per la semi-sfera come argomento appare un versore, che ne individua l'orientazione
|
||||
// nello spazio. Si immagini uno spazio con origine nel centro della sfera e asse Z diretto come tale
|
||||
// versore. La sfera è divisa in due parti: una nel semi spazio Z+ e una in quello Z-.
|
||||
@@ -34,11 +33,6 @@
|
||||
// Costanti tipologia di componente lineare
|
||||
enum LinType { Line = 0, Ray = 1, Segment = 2} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
|
||||
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) ;
|
||||
|
||||
|
||||
// Costanti tipologia di intersezioni fra un componente lineare e un disco
|
||||
enum LinCompDiscIntersType { D_ERROR_INT = -1, D_NO_INTERS = 0, D_BOUNDARY_INT_LINE_NOT_IN_PLANE = 1,
|
||||
D_INNER_INT_LINE_NOT_IN_PLANE = 2, D_ONE_INT_LINE_ON_PLANE = 3,
|
||||
@@ -135,7 +129,7 @@ int IntersRayInfiniteCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Valuta la posizione reciproca fra un cilindro infinito e un segmento.
|
||||
// Nel caso in cui il sgmento giaccia sul cilindro, nIntType vale INF_INT e dU1 e dU2
|
||||
// Nel caso in cui il segmento giaccia sul cilindro, nIntType vale INF_INT e dU1 e dU2
|
||||
// valgono rispettivamente 0 e dLen (lunghezza del segmento).
|
||||
int IntersSegmentInfiniteCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double dLen,
|
||||
const Point3d& ptPCyl, const Vector3d& vtVCyl, double dCylRad,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2019
|
||||
// EgalTech 2015-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineSurfTm.cpp Data : 09.03.15 Versione : 2.1b6
|
||||
// File : IntersLineSurfTm.cpp Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Implementazione della intersezione linea/superficie trimesh.
|
||||
//
|
||||
//
|
||||
@@ -14,8 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "ProjPlane.h"
|
||||
#include "IntersLineSurfStd.h"
|
||||
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
|
||||
|
||||
+34
-6
@@ -1,8 +1,8 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineBox.cpp Data : 07.05.20 Versione : 2.2e1
|
||||
// Contenuto : Implementazione della intersezione linea/box.
|
||||
// File : IntersPlaneBox.cpp Data : 07.05.20 Versione : 2.2e1
|
||||
// Contenuto : Implementazione della intersezione piano/box.
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -20,19 +20,47 @@
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Box e piano devono essere nello stesso riferimento. Il box deve essere axis aligned.
|
||||
bool
|
||||
IntersPlaneBox( const Point3d& ptOn, const Vector3d& vtN, const BBox3d& b3Box,
|
||||
TestIntersPlaneBox( const Plane3d& plPlane, const BBox3d& b3Box)
|
||||
{
|
||||
// Verifica del piano
|
||||
if ( ! plPlane.IsValid())
|
||||
return false ;
|
||||
// Centro e estensione del box
|
||||
Point3d ptCen ;
|
||||
Vector3d vtExt ;
|
||||
if ( ! b3Box.GetCenterExtent( ptCen, vtExt))
|
||||
return false ;
|
||||
// Distanza del centro dal piano
|
||||
double dDist = DistPointPlane( ptCen, plPlane) ;
|
||||
// Proiezione dell'estensione sulla normale al piano
|
||||
Vector3d vtN = plPlane.GetVersN() ;
|
||||
double dProjExt = vtExt.x * abs( vtN.x) + vtExt.y * abs( vtN.y) + vtExt.z * abs( vtN.z) ;
|
||||
// Confronto distanza del centro con estensione proiettata
|
||||
return ( abs( dDist) < dProjExt + EPS_SMALL) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersPlaneBox( const Plane3d& plPlane, const BBox3d& b3Box,
|
||||
PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria)
|
||||
{
|
||||
// Creo il piano
|
||||
Plane3d plPlane ;
|
||||
if ( ! plPlane.Set( ptOn, vtN))
|
||||
// Verifico il piano
|
||||
if ( ! plPlane.IsValid())
|
||||
return false ;
|
||||
// Recupero i dati del Box
|
||||
Point3d ptMin ;
|
||||
double dDimX, dDimY, dDimZ ;
|
||||
if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimZ))
|
||||
return false ;
|
||||
// Pulisco vettori intersezioni
|
||||
vPnt.clear() ;
|
||||
vBpt.clear() ;
|
||||
vTria.clear() ;
|
||||
// Verifico se può esistere intersezione
|
||||
if ( ! TestIntersPlaneBox( plPlane, b3Box))
|
||||
return true ;
|
||||
// Contorno di base
|
||||
PolyLine PL ;
|
||||
PL.AddUPoint( 0, ptMin) ;
|
||||
|
||||
+223
-97
@@ -27,102 +27,39 @@
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Intersezione di un piano con una superficie TriMesh
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm,
|
||||
PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria)
|
||||
{
|
||||
// verifico piano
|
||||
if ( &plPlane == nullptr || plPlane.GetVersN().IsSmall())
|
||||
return false ;
|
||||
// verifico superficie
|
||||
if ( &Stm == nullptr || ! Stm.IsValid())
|
||||
return false ;
|
||||
// verifico parametri di ritorno
|
||||
if ( &vPnt == nullptr || &vBpt == nullptr || &vTria == nullptr)
|
||||
return false ;
|
||||
vPnt.clear() ;
|
||||
vBpt.clear() ;
|
||||
vTria.clear() ;
|
||||
|
||||
// per ricerca veloce di punti ripetuti
|
||||
PointGrid3d PtGrid ;
|
||||
PtGrid.Init( 100) ;
|
||||
|
||||
// per ricerca veloce di linee ripetute
|
||||
HashGrids3d LnGrid ;
|
||||
LnGrid.SetActivationGrid( true) ;
|
||||
|
||||
// per ricerca veloce di triangoli ripetuti
|
||||
HashGrids3d TrGrid ;
|
||||
TrGrid.SetActivationGrid( true) ;
|
||||
|
||||
// cerco i triangoli intersecati dal piano
|
||||
Triangle3d Tria ;
|
||||
int nT = Stm.GetFirstTriangle( Tria) ;
|
||||
while ( nT != SVT_NULL) {
|
||||
// intersezione tra il piano e il triangolo
|
||||
Point3d ptInt, ptInt2 ;
|
||||
int nRes = IntersPlaneTria( plPlane, Tria, ptInt, ptInt2) ;
|
||||
// se vertice
|
||||
if ( nRes == IPTT_VERT) {
|
||||
// verifico se punto già inserito
|
||||
int nId ;
|
||||
if ( ! PtGrid.Find( ptInt, 10 * EPS_SMALL, nId)) {
|
||||
vPnt.emplace_back( ptInt) ;
|
||||
PtGrid.InsertPoint( ptInt, int( vPnt.size()) - 1) ;
|
||||
}
|
||||
static void
|
||||
UpdateIntersPlaneSurfTm( const Plane3d& plPlane, const Triangle3d& Tria, PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria,
|
||||
PointGrid3d& PtGrid, HashGrids3d& LnGrid, HashGrids3d& TrGrid)
|
||||
{
|
||||
// intersezione tra il piano e il triangolo
|
||||
Point3d ptInt, ptInt2 ;
|
||||
int nRes = IntersPlaneTria( plPlane, Tria, ptInt, ptInt2) ;
|
||||
// se vertice
|
||||
if ( nRes == IPTT_VERT) {
|
||||
// verifico se punto già inserito
|
||||
int nId ;
|
||||
if ( ! PtGrid.Find( ptInt, 10 * EPS_SMALL, nId)) {
|
||||
vPnt.emplace_back( ptInt) ;
|
||||
PtGrid.InsertPoint( ptInt, int( vPnt.size()) - 1) ;
|
||||
}
|
||||
// se altrimenti segmento
|
||||
else if ( nRes == IPTT_EDGE || nRes == IPTT_YES) {
|
||||
// se abbastanza lungo
|
||||
if ( ! AreSamePointApprox( ptInt, ptInt2)) {
|
||||
// verifico se già inserito
|
||||
bool bFound = false ;
|
||||
BBox3d b3Line( ptInt, ptInt2) ;
|
||||
INTVECTOR vnIds ;
|
||||
if ( LnGrid.Find( b3Line, vnIds)) {
|
||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
||||
int nA = vnIds[i] ;
|
||||
const Point3d& ptOth = vBpt[nA].first ;
|
||||
const Point3d& ptOth2 = vBpt[nA].second ;
|
||||
if ( ( AreSamePointEpsilon( ptInt, ptOth, 10 * EPS_SMALL) &&
|
||||
AreSamePointEpsilon( ptInt2, ptOth2, 10 * EPS_SMALL)) ||
|
||||
( AreSamePointEpsilon( ptInt, ptOth2, 10 * EPS_SMALL) &&
|
||||
AreSamePointEpsilon( ptInt2, ptOth, 10 * EPS_SMALL))) {
|
||||
bFound = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se non inserito, procedo
|
||||
if ( ! bFound) {
|
||||
vBpt.emplace_back( ptInt, ptInt2) ;
|
||||
LnGrid.Add( int( vBpt.size()) - 1, b3Line) ;
|
||||
LnGrid.Update() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se altrimenti l'intero triangolo
|
||||
else if ( nRes == IPTT_OVERLAPS) {
|
||||
// verifico se triangolo già inserito
|
||||
}
|
||||
// se altrimenti segmento
|
||||
else if ( nRes == IPTT_EDGE || nRes == IPTT_YES) {
|
||||
// se abbastanza lungo
|
||||
if ( ! AreSamePointApprox( ptInt, ptInt2)) {
|
||||
// verifico se già inserito
|
||||
bool bFound = false ;
|
||||
BBox3d b3Tria( Tria.GetP( 0), Tria.GetP( 1)) ;
|
||||
b3Tria.Add( Tria.GetP( 2)) ;
|
||||
BBox3d b3Line( ptInt, ptInt2) ;
|
||||
INTVECTOR vnIds ;
|
||||
if ( TrGrid.Find( b3Tria, vnIds)) {
|
||||
if ( LnGrid.Find( b3Line, vnIds)) {
|
||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
||||
int nA = vnIds[i] ;
|
||||
const Triangle3d& trOth = vTria[nA] ;
|
||||
array< bool, 3> bOth = { false, false, false} ;
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
for ( int k = 0 ; k < 3 ; ++ k) {
|
||||
if ( ! bOth[k])
|
||||
bOth[k] = AreSamePointEpsilon( Tria.GetP( j), trOth.GetP( k), 10 * EPS_SMALL) ;
|
||||
}
|
||||
}
|
||||
if ( bOth[0] && bOth[1] && bOth[2]) {
|
||||
const Point3d& ptOth = vBpt[nA].first ;
|
||||
const Point3d& ptOth2 = vBpt[nA].second ;
|
||||
if ( ( AreSamePointEpsilon( ptInt, ptOth, 10 * EPS_SMALL) &&
|
||||
AreSamePointEpsilon( ptInt2, ptOth2, 10 * EPS_SMALL)) ||
|
||||
( AreSamePointEpsilon( ptInt, ptOth2, 10 * EPS_SMALL) &&
|
||||
AreSamePointEpsilon( ptInt2, ptOth, 10 * EPS_SMALL))) {
|
||||
bFound = true ;
|
||||
break ;
|
||||
}
|
||||
@@ -130,15 +67,52 @@ IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm,
|
||||
}
|
||||
// se non inserito, procedo
|
||||
if ( ! bFound) {
|
||||
vTria.emplace_back( Tria) ;
|
||||
TrGrid.Add( int( vTria.size()) - 1, b3Tria) ;
|
||||
TrGrid.Update() ;
|
||||
vBpt.emplace_back( ptInt, ptInt2) ;
|
||||
LnGrid.Add( int( vBpt.size()) - 1, b3Line) ;
|
||||
LnGrid.Update() ;
|
||||
}
|
||||
}
|
||||
// passo al prossimo triangolo
|
||||
nT = Stm.GetNextTriangle( nT, Tria) ;
|
||||
}
|
||||
// se altrimenti l'intero triangolo
|
||||
else if ( nRes == IPTT_OVERLAPS) {
|
||||
// verifico se triangolo già inserito
|
||||
bool bFound = false ;
|
||||
BBox3d b3Tria( Tria.GetP( 0), Tria.GetP( 1)) ;
|
||||
b3Tria.Add( Tria.GetP( 2)) ;
|
||||
INTVECTOR vnIds ;
|
||||
if ( TrGrid.Find( b3Tria, vnIds)) {
|
||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
||||
int nA = vnIds[i] ;
|
||||
const Triangle3d& trOth = vTria[nA] ;
|
||||
array< bool, 3> bOth = { false, false, false} ;
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
for ( int k = 0 ; k < 3 ; ++ k) {
|
||||
if ( ! bOth[k])
|
||||
bOth[k] = AreSamePointEpsilon( Tria.GetP( j), trOth.GetP( k), 10 * EPS_SMALL) ;
|
||||
}
|
||||
}
|
||||
if ( bOth[0] && bOth[1] && bOth[2]) {
|
||||
bFound = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se non inserito, procedo
|
||||
if ( ! bFound) {
|
||||
vTria.emplace_back( Tria) ;
|
||||
TrGrid.Add( int( vTria.size()) - 1, b3Tria) ;
|
||||
TrGrid.Update() ;
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static void
|
||||
AdjustIntersPlaneSurfTm( PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria,
|
||||
const Plane3d& plPlane, const HashGrids3d& LnGrid, const HashGrids3d& TrGrid)
|
||||
{
|
||||
// rimuovo i punti che stanno sui segmenti
|
||||
for ( int i = int( vPnt.size()) - 1 ; i >= 0 ; -- i) {
|
||||
bool bFound = false ;
|
||||
@@ -190,7 +164,7 @@ IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm,
|
||||
int nA = vnIds[j] ;
|
||||
const Triangle3d& trOth = vTria[nA] ;
|
||||
if ( DistPointTriangle( ptStart, trOth).IsEpsilon( 10 * EPS_SMALL) &&
|
||||
DistPointTriangle( ptEnd, trOth).IsEpsilon( 10 * EPS_SMALL)) {
|
||||
DistPointTriangle( ptEnd, trOth).IsEpsilon( 10 * EPS_SMALL)) {
|
||||
bFound = true ;
|
||||
break ;
|
||||
}
|
||||
@@ -200,5 +174,157 @@ IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm,
|
||||
vBpt.erase( vBpt.begin() + i) ;
|
||||
}
|
||||
|
||||
// porto i punti esattamente nel piano
|
||||
for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) {
|
||||
vPnt[i] = ProjectPointOnPlane( vPnt[i], plPlane) ;
|
||||
}
|
||||
|
||||
// porto i segmenti esattamente nel piano
|
||||
for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) {
|
||||
vBpt[i].first = ProjectPointOnPlane( vBpt[i].first, plPlane) ;
|
||||
vBpt[i].second = ProjectPointOnPlane( vBpt[i].second, plPlane) ;
|
||||
}
|
||||
|
||||
// porto i triangoli esattamente nel piano
|
||||
for ( int i = 0 ; i < int( vTria.size()) ; ++ i) {
|
||||
Triangle3d& trTria = vTria[i] ;
|
||||
trTria.SetP( 0, ProjectPointOnPlane( trTria.GetP( 0), plPlane)) ;
|
||||
trTria.SetP( 1, ProjectPointOnPlane( trTria.GetP( 1), plPlane)) ;
|
||||
trTria.SetP( 2, ProjectPointOnPlane( trTria.GetP( 2), plPlane)) ;
|
||||
trTria.Validate( true) ;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Intersezione di un piano con una superficie TriMesh
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm,
|
||||
PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria)
|
||||
{
|
||||
// verifico piano
|
||||
if ( &plPlane == nullptr || plPlane.GetVersN().IsSmall())
|
||||
return false ;
|
||||
// verifico superficie
|
||||
if ( &Stm == nullptr || ! Stm.IsValid())
|
||||
return false ;
|
||||
// verifico parametri di ritorno
|
||||
if ( &vPnt == nullptr || &vBpt == nullptr || &vTria == nullptr)
|
||||
return false ;
|
||||
vPnt.clear() ;
|
||||
vBpt.clear() ;
|
||||
vTria.clear() ;
|
||||
|
||||
// per ricerca veloce di punti ripetuti
|
||||
PointGrid3d PtGrid ;
|
||||
PtGrid.Init( 100) ;
|
||||
|
||||
// per ricerca veloce di linee ripetute
|
||||
HashGrids3d LnGrid ;
|
||||
LnGrid.SetActivationGrid( true) ;
|
||||
|
||||
// per ricerca veloce di triangoli ripetuti
|
||||
HashGrids3d TrGrid ;
|
||||
TrGrid.SetActivationGrid( true) ;
|
||||
|
||||
// cerco i triangoli intersecati dal piano
|
||||
Triangle3d Tria ;
|
||||
int nT = Stm.GetFirstTriangle( Tria) ;
|
||||
while ( nT != SVT_NULL) {
|
||||
UpdateIntersPlaneSurfTm( plPlane, Tria, vPnt, vBpt, vTria, PtGrid, LnGrid, TrGrid) ;
|
||||
nT = Stm.GetNextTriangle( nT, Tria) ;
|
||||
}
|
||||
|
||||
AdjustIntersPlaneSurfTm( vPnt, vBpt, vTria, plPlane, LnGrid, TrGrid) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Intersezione di molti piani paralleli con una superficie TriMesh
|
||||
//----------------------------------------------------------------------------
|
||||
IntersParPlanesSurfTm::IntersParPlanesSurfTm( const Frame3d& frPlanes, const ISurfTriMesh& Stm)
|
||||
: m_bOk( false), m_frPlanes( frPlanes), m_pSTm( &Stm)
|
||||
{
|
||||
// verifico esistenza superficie
|
||||
if ( m_pSTm == nullptr || ! m_pSTm->IsValid())
|
||||
return ;
|
||||
|
||||
// creo HashGrid 1d
|
||||
const int LIM_HG_TRIA = 127 ;
|
||||
m_HGrids.SetActivationGrid( m_pSTm->GetTriangleCount() > LIM_HG_TRIA) ;
|
||||
|
||||
// riempio HashGrid
|
||||
Triangle3d Tria ;
|
||||
int nT = Stm.GetFirstTriangle( Tria) ;
|
||||
while ( nT != SVT_NULL) {
|
||||
// calcolo il BBox del triangolo nel riferimento dei piani
|
||||
Tria.ToLoc( m_frPlanes) ;
|
||||
BBox3d b3Tria ;
|
||||
b3Tria.Add( Tria.GetP( 0)) ;
|
||||
b3Tria.Add( Tria.GetP( 1)) ;
|
||||
b3Tria.Add( Tria.GetP( 2)) ;
|
||||
// inserisco nella griglia
|
||||
if ( ! m_HGrids.Add( nT, b3Tria))
|
||||
return ;
|
||||
// passo al prossimo triangolo
|
||||
nT = Stm.GetNextTriangle( nT, Tria) ;
|
||||
}
|
||||
// aggiorno
|
||||
m_bOk = m_HGrids.Update() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersParPlanesSurfTm::GetInters( double dDist, PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria) const
|
||||
{
|
||||
// verifico validità
|
||||
if ( ! m_bOk)
|
||||
return false ;
|
||||
|
||||
// verifico parametri di ritorno
|
||||
if ( &vPnt == nullptr || &vBpt == nullptr || &vTria == nullptr)
|
||||
return false ;
|
||||
vPnt.clear() ;
|
||||
vBpt.clear() ;
|
||||
vTria.clear() ;
|
||||
|
||||
// per ricerca veloce di punti ripetuti
|
||||
PointGrid3d PtGrid ;
|
||||
PtGrid.Init( 100) ;
|
||||
|
||||
// per ricerca veloce di linee ripetute
|
||||
HashGrids3d LnGrid ;
|
||||
LnGrid.SetActivationGrid( true) ;
|
||||
|
||||
// per ricerca veloce di triangoli ripetuti
|
||||
HashGrids3d TrGrid ;
|
||||
TrGrid.SetActivationGrid( true) ;
|
||||
|
||||
// calcolo il piano ( in globale)
|
||||
Point3d ptPl = m_frPlanes.Orig() + dDist * m_frPlanes.VersZ() ;
|
||||
Plane3d plPlane ;
|
||||
plPlane.Set( ptPl, m_frPlanes.VersZ()) ;
|
||||
|
||||
// calcolo box del piano ( nel riferimento)
|
||||
BBox3d b3Plane ;
|
||||
b3Plane.Add( Point3d( 0, 0, dDist)) ;
|
||||
b3Plane.Expand( INFINITO - 1 , INFINITO - 1, 0) ;
|
||||
|
||||
// recupero indici triangoli che intersecano box
|
||||
INTVECTOR vnIds ;
|
||||
if ( m_HGrids.Find( b3Plane, vnIds)) {
|
||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
||||
int nT = vnIds[i] ;
|
||||
Triangle3d Tria ;
|
||||
m_pSTm->GetTriangle( nT, Tria) ;
|
||||
UpdateIntersPlaneSurfTm( plPlane, Tria, vPnt, vBpt, vTria, PtGrid, LnGrid, TrGrid) ;
|
||||
}
|
||||
}
|
||||
|
||||
AdjustIntersPlaneSurfTm( vPnt, vBpt, vTria, plPlane, LnGrid, TrGrid) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "/EgtDev/Include/EGkPointGrid3d.h"
|
||||
#include "/EgtDev/Include/EGkHashGrids3d.h"
|
||||
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||
#include "/EgtDev/Include/EgnStringUtils.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include <array>
|
||||
|
||||
using namespace std ;
|
||||
@@ -116,7 +116,7 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
|
||||
}
|
||||
}
|
||||
// se altrimenti sovrapposizione
|
||||
else if ( nRes == ITTT_OVERLAPS) {
|
||||
else if ( nRes == ITTT_OVERLAPS || nRes == ITTT_COUNTER_OVERLAPS) {
|
||||
for ( const auto& Tria : vIttTria) {
|
||||
// verifico se triangolo già inserito
|
||||
bool bFound = false ;
|
||||
|
||||
+34
-5
@@ -83,8 +83,37 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
|
||||
// se i triangoli sono complanari
|
||||
if ( nResPP == IPPT_OVERLAPS ||
|
||||
((( nVertPos1 == 0 && nVertNeg1 == 0) || ( nVertPos2 == 0 && nVertNeg2 == 0)) &&
|
||||
( trTria1.GetN() ^ trTria2.GetN()).SqLen() < 25 * SIN_EPS_ANG_SMALL * SIN_EPS_ANG_SMALL))
|
||||
return IntersCoplanarTriaTria( trTria1, trTria2, vTria) ;
|
||||
( trTria1.GetN() ^ trTria2.GetN()).SqLen() < 25 * SIN_EPS_ANG_SMALL * SIN_EPS_ANG_SMALL)) {
|
||||
// verifica per triangoli con normali controverse
|
||||
bool bCounter = false ;
|
||||
Triangle3d trMyTria2 = trTria2 ;
|
||||
if ( trTria1.GetN() * trTria2.GetN() < 0) {
|
||||
Point3d ptV0 = trMyTria2.GetP( 0) ;
|
||||
trMyTria2.SetP( 0, trMyTria2.GetP( 1)) ;
|
||||
trMyTria2.SetP( 1, ptV0) ;
|
||||
trMyTria2.Validate() ;
|
||||
bCounter = true ;
|
||||
}
|
||||
// verifica per triangoli coincidenti
|
||||
bool bAreSameTria = ( ( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 0)) &&
|
||||
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 1)) &&
|
||||
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 2))) ||
|
||||
( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 1)) &&
|
||||
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 2)) &&
|
||||
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 0))) ||
|
||||
( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 2)) &&
|
||||
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 0)) &&
|
||||
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 1)))) &&
|
||||
( AreSameVectorExact( trTria1.GetN(), trMyTria2.GetN())) ;
|
||||
if ( bAreSameTria) {
|
||||
vTria.emplace_back( trTria1) ;
|
||||
return ( bCounter ? ITTT_COUNTER_OVERLAPS : ITTT_OVERLAPS) ;
|
||||
}
|
||||
if ( ITTT_OVERLAPS == IntersCoplanarTriaTria( trTria1, trMyTria2, vTria)) {
|
||||
return ( bCounter ? ITTT_COUNTER_OVERLAPS : ITTT_OVERLAPS) ;
|
||||
}
|
||||
return ITTT_NO ;
|
||||
}
|
||||
|
||||
// limito la linea di intersezione con il primo triangolo
|
||||
Point3d ptSt1, ptEn1 ;
|
||||
@@ -112,7 +141,7 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
|
||||
int
|
||||
IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TRIA3DVECTOR& vTria)
|
||||
{
|
||||
// Se i tre vertici del secondo triangolo stanno tutti a destra di almeno un lato del primo, non c'è intersezione
|
||||
// Se i tre vertici del secondo triangolo stanno tutti a destra di almeno un lato del primo, non c'� intersezione
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
Vector3d vtSide = trTria1.GetP( ( i + 1) % 3) - trTria1.GetP( i) ;
|
||||
Vector3d vtSN = vtSide ^ trTria1.GetN() ;
|
||||
@@ -122,7 +151,7 @@ IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TR
|
||||
( trTria2.GetP( 2) - trTria1.GetP( i)) * vtSN > - EPS_TRIA_H)
|
||||
return ITTT_NO ;
|
||||
}
|
||||
// Se i tre vertici del primo triangolo stanno tutti a destra di almeno un lato del secondo, non c'è intersezione
|
||||
// Se i tre vertici del primo triangolo stanno tutti a destra di almeno un lato del secondo, non c'� intersezione
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
Vector3d vtSide = trTria2.GetP( ( i + 1) % 3) - trTria2.GetP( i) ;
|
||||
Vector3d vtSN = vtSide ^ trTria2.GetN() ;
|
||||
@@ -205,7 +234,7 @@ int
|
||||
FindTriaTriaIntersType( const Triangle3d& trTria1, const Triangle3d& trTria2, const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
double dStU1, double dEnU1, double dStU2, double dEnU2, int nRes1, int nRes2, double& dIntStU, double& dIntEnU)
|
||||
{
|
||||
// Controllo su validità input
|
||||
// Controllo su validit� input
|
||||
if ( ! ( trTria1.IsValid() && trTria2.IsValid() && vtLineDir.IsNormalized()))
|
||||
return ITTT_NO ;
|
||||
// Casi
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "/EgtDev/Include/EgkLinePerpTwoCurves.h"
|
||||
#include "/EgtDev/Include/EgkLinePntPerpCurve.h"
|
||||
#include "/EgtDev/Include/EgkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkLinePerpTwoCurves.h"
|
||||
#include "/EgtDev/Include/EGkLinePntPerpCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user