Merge branch '3dm_import+trim&mesh'
This commit is contained in:
+9
-9
@@ -101,7 +101,7 @@ Attribs::Save( NgeWriter& ngeOut) const
|
||||
// modo
|
||||
if ( ! ngeOut.WriteUchar( m_Data[MODE], ","))
|
||||
return false ;
|
||||
// stato (se SEL è convertito in ON)
|
||||
// stato (se SEL � convertito in ON)
|
||||
int nStat = (( m_Data[STATUS] > GDB_ST_ON) ? GDB_ST_ON : m_Data[STATUS]) ;
|
||||
if ( ! ngeOut.WriteUchar( nStat, ","))
|
||||
return false ;
|
||||
@@ -141,7 +141,7 @@ Attribs::Load( NgeReader& ngeIn)
|
||||
if ( ! ngeIn.ReadUchar( ucMode, ","))
|
||||
return false ;
|
||||
m_Data[MODE] = CLIP( ucMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
||||
// stato (se SEL è convertito in ON)
|
||||
// stato (se SEL � convertito in ON)
|
||||
unsigned char ucStat ;
|
||||
if ( ! ngeIn.ReadUchar( ucStat, ","))
|
||||
return false ;
|
||||
@@ -177,7 +177,7 @@ Attribs::Load( NgeReader& ngeIn)
|
||||
bool
|
||||
Attribs::DataFromString( const string& sParam)
|
||||
{
|
||||
// il primo parametro è diviso in 4 parti
|
||||
// il primo parametro � diviso in 4 parti
|
||||
STRVECTOR vsParams ;
|
||||
Tokenize( sParam, ",", vsParams) ;
|
||||
// 4 parti
|
||||
@@ -215,7 +215,7 @@ Attribs::SetName( const string& sName)
|
||||
if ( sName.empty() || ! IsValidVal( sName))
|
||||
return false ;
|
||||
|
||||
// può essere solo la prima stringa
|
||||
// pu� essere solo la prima stringa
|
||||
STRLIST::iterator iIter ;
|
||||
if ( ( iIter = m_slInfo.begin()) != m_slInfo.end() &&
|
||||
FindKey( *iIter, NAME)) {
|
||||
@@ -237,7 +237,7 @@ Attribs::SetName( const string& sName)
|
||||
bool
|
||||
Attribs::GetName( string& sName) const
|
||||
{
|
||||
// può essere solo la prima stringa
|
||||
// pu� essere solo la prima stringa
|
||||
STRLIST::const_iterator iIter ;
|
||||
if ( ( iIter = m_slInfo.begin()) != m_slInfo.end() &&
|
||||
FindKey( *iIter, NAME)) {
|
||||
@@ -252,7 +252,7 @@ Attribs::GetName( string& sName) const
|
||||
bool
|
||||
Attribs::ExistsName( void) const
|
||||
{
|
||||
// può essere solo la prima stringa
|
||||
// pu� essere solo la prima stringa
|
||||
STRLIST::const_iterator iIter ;
|
||||
if ( ( iIter = m_slInfo.begin()) != m_slInfo.end() &&
|
||||
FindKey( *iIter, NAME))
|
||||
@@ -265,7 +265,7 @@ Attribs::ExistsName( void) const
|
||||
bool
|
||||
Attribs::RemoveName( void)
|
||||
{
|
||||
// può essere solo la prima stringa
|
||||
// pu� essere solo la prima stringa
|
||||
STRLIST::const_iterator iIter ;
|
||||
if ( ( iIter = m_slInfo.begin()) != m_slInfo.end() &&
|
||||
FindKey( *iIter, NAME)) {
|
||||
@@ -285,11 +285,11 @@ Attribs::SetInfo( const string& sKey, const string& sVal)
|
||||
if ( ! IsValidKey( sKey) || sVal.empty() || ! IsValidVal( sVal))
|
||||
return false ;
|
||||
|
||||
// se è il nome
|
||||
// se � il nome
|
||||
if ( sKey == NAME)
|
||||
return SetName( sVal) ;
|
||||
|
||||
// se esiste già una stringa con quella chiave la sostituisco
|
||||
// se esiste gi� una stringa con quella chiave la sostituisco
|
||||
for ( auto iIter = m_slInfo.begin() ; iIter != m_slInfo.end() ; ++ iIter) {
|
||||
if ( FindKey( *iIter, sKey)) {
|
||||
*iIter = sKey + EQUAL + sVal ;
|
||||
|
||||
+199
-11
@@ -510,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)
|
||||
@@ -526,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 || ! cnData.bClamped) {
|
||||
// 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 ;
|
||||
@@ -558,7 +720,7 @@ NurbsToBezierCurve( const CNurbsData& cnData)
|
||||
}
|
||||
if ( ! bOk)
|
||||
return nullptr ;
|
||||
|
||||
|
||||
// se 1 solo intervallo, la Nurbs è già una curva di Bezier
|
||||
if ( nInt == 1) {
|
||||
// creo la curva di Bezier
|
||||
@@ -617,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)
|
||||
@@ -684,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) {
|
||||
@@ -708,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) ;
|
||||
}
|
||||
|
||||
@@ -342,6 +342,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="IntersPlaneTria.cpp" />
|
||||
<ClCompile Include="IntersSurfTmSurfTm.cpp" />
|
||||
<ClCompile Include="IntersTriaTria.cpp" />
|
||||
<ClCompile Include="Tree.cpp" />
|
||||
<ClCompile Include="MedialAxis.cpp" />
|
||||
<ClCompile Include="OffsetCurve.cpp" />
|
||||
<ClCompile Include="DistPointArc.cpp" />
|
||||
@@ -402,6 +403,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="SelfIntersCurve.cpp" />
|
||||
<ClCompile Include="SfrCreate.cpp" />
|
||||
<ClCompile Include="SubtractProjectedFacesOnStmFace.cpp" />
|
||||
<ClCompile Include="SurfAux.cpp" />
|
||||
<ClCompile Include="SurfBezier.cpp" />
|
||||
<ClCompile Include="SurfFlatRegion.cpp" />
|
||||
<ClCompile Include="SurfFlatRegionBooleans.cpp" />
|
||||
@@ -611,6 +613,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="IntersLineSurfStd.h" />
|
||||
<ClInclude Include="IntersLineTria.h" />
|
||||
<ClInclude Include="IterManager.h" />
|
||||
<ClInclude Include="Tree.h" />
|
||||
<ClInclude Include="Material.h" />
|
||||
<ClInclude Include="FontNfe.h" />
|
||||
<ClInclude Include="MC_Tables.h" />
|
||||
@@ -622,6 +625,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="AdjustLoops.h" />
|
||||
<ClInclude Include="RemoveCurveDefects.h" />
|
||||
<ClInclude Include="EGkSubtractProjectedFacesOnStmFace.h" />
|
||||
<ClInclude Include="SurfAux.h" />
|
||||
<ClInclude Include="SurfBezier.h" />
|
||||
<ClInclude Include="SurfFlatRegion.h" />
|
||||
<ClInclude Include="TextureData.h" />
|
||||
|
||||
@@ -474,6 +474,9 @@
|
||||
<ClCompile Include="MedialAxis.cpp">
|
||||
<Filter>File di origine\GeoOffset</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Tree.cpp">
|
||||
<Filter>File di origine\Base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersLineCyl.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
@@ -489,6 +492,9 @@
|
||||
<ClCompile Include="SubtractProjectedFacesOnStmFace.cpp">
|
||||
<Filter>File di origine\GeoProject</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SurfAux.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -1121,6 +1127,9 @@
|
||||
<ClInclude Include="CDeCapsTria.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Tree.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntersLineCyl.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
@@ -1133,6 +1142,9 @@
|
||||
<ClInclude Include="EGkSubtractProjectedFacesOnStmFace.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SurfAux.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+14
-13
@@ -4,7 +4,7 @@
|
||||
// File : StmFromTriangleSoup.cpp Data : 07.05.23 Versione : 2.5e2
|
||||
// Contenuto : Implementazione della classe StmFromTriangleSoup, per creare
|
||||
// una superficie trimesh da un insieme di triangoli
|
||||
// (può essere disordinato come STL o può essere una superficie).
|
||||
// (pu� essere disordinato come STL o pu� essere una superficie).
|
||||
//
|
||||
// Modifiche : 19.05.14 DS Creazione modulo.
|
||||
//
|
||||
@@ -53,7 +53,7 @@ StmFromTriangleSoup::AddTriangle( const Triangle3d& Tria)
|
||||
// ciclo sui tre vertici
|
||||
int nIdV[3] ;
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
// verifico se vertice già presente
|
||||
// verifico se vertice gi� presente
|
||||
int nId ;
|
||||
if ( ! m_VertGrid.Find( Tria.GetP( i), 2 * EPS_SMALL, nId)) {
|
||||
// aggiungo il vertice
|
||||
@@ -76,37 +76,38 @@ StmFromTriangleSoup::AddTriangle( const Triangle3d& Tria)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2)
|
||||
StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2,
|
||||
const double dU0, const double dV0,const double dU1, const double dV1,const double dU2, const double dV2)
|
||||
{
|
||||
// verifico inizializzazione
|
||||
// verifico inizializzazione
|
||||
if ( m_pSTM == nullptr)
|
||||
return false ;
|
||||
// ciclo sui tre vertici
|
||||
// ciclo sui tre vertici
|
||||
int nIdV[3] ;
|
||||
if ( ( nIdV[0] = AddVertex( ptP0)) == SVT_NULL)
|
||||
if ( ( nIdV[0] = AddVertex( ptP0, dU0, dV0)) == SVT_NULL)
|
||||
return false ;
|
||||
if ( ( nIdV[1] = AddVertex( ptP1)) == SVT_NULL)
|
||||
if ( ( nIdV[1] = AddVertex( ptP1, dU1, dV1)) == SVT_NULL)
|
||||
return false ;
|
||||
if ( ( nIdV[2] = AddVertex( ptP2)) == SVT_NULL)
|
||||
if ( ( nIdV[2] = AddVertex( ptP2, dU2, dV2)) == SVT_NULL)
|
||||
return false ;
|
||||
// se i vertici sono tutti diversi tra loro, inserisco il triangolo
|
||||
// se i vertici sono tutti diversi tra loro, inserisco il triangolo
|
||||
if ( nIdV[0] != nIdV[1] && nIdV[0] != nIdV[2] && nIdV[1] != nIdV[2]) {
|
||||
if ( m_pSTM->AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
StmFromTriangleSoup::AddVertex( const Point3d& ptP)
|
||||
StmFromTriangleSoup::AddVertex( const Point3d& ptP, const double dU, const double dV)
|
||||
{
|
||||
// verifico se già presente
|
||||
// verifico se gi� presente
|
||||
int nId ;
|
||||
if ( m_VertGrid.Find( ptP, 2 * EPS_SMALL, nId))
|
||||
return nId ;
|
||||
// aggiungo il vertice
|
||||
if ( ( nId = m_pSTM->AddVertex( ptP)) == SVT_NULL)
|
||||
if ( ( nId = m_pSTM->AddVertex( ptP, dU, dV)) == SVT_NULL)
|
||||
return SVT_NULL ;
|
||||
m_VertGrid.InsertPoint( ptP, nId) ;
|
||||
return nId ;
|
||||
|
||||
+497
@@ -0,0 +1,497 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfAux.cpp Data : 09.08.23 Versione :
|
||||
// Contenuto : Implementazione di alcune funzioni di utilit? per le Superfici.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 09.08.23 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveAux.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include "/EgtDev/Include/EGkSurf.h"
|
||||
#include "/EgtDev/Include/EGkSurfAux.h"
|
||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
bool
|
||||
NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
||||
{
|
||||
// per rendere una superficie non periodica devo recuperare i punti di controllo, suddivisi in isoparametriche lungo una direzione
|
||||
// e applicare la trasformazione ad ogni isoparametrica, sostituendola poi a quella originale. ( si mantiene il numero di punti)
|
||||
if ( snData.bPeriodicU || ! snData.bClampedU) {
|
||||
bool bIsRational = snData.bRat ;
|
||||
// vettore dei nodi
|
||||
DBLVECTOR vU ;
|
||||
int nKnot = (int) snData.vU.size() ;
|
||||
for ( int k = 0 ; k < nKnot ; ++k ) {
|
||||
double dKnot = snData.vU[k] ;
|
||||
vU.push_back( dKnot) ;
|
||||
}
|
||||
for( int j = 0 ; j < snData.nCPV ; ++j) {
|
||||
CNurbsData nuCurve ;
|
||||
nuCurve.bPeriodic = true ;
|
||||
nuCurve.nDeg = snData.nDegU ;
|
||||
nuCurve.vU = vU ;
|
||||
// vettore dei punti di controllo
|
||||
PNTVECTOR vPtCtrl ;
|
||||
// vettore dei pesi
|
||||
DBLVECTOR vWeCtrl ;
|
||||
for ( int i = 0 ; i < snData.nCPU ; ++i ) {
|
||||
if ( bIsRational) {
|
||||
vPtCtrl.push_back( snData.mCP[i][j] / snData.mW[i][j]) ;
|
||||
vWeCtrl.push_back( snData.mW[i][j]) ;
|
||||
}
|
||||
else
|
||||
vPtCtrl.push_back( snData.mCP[i][j]) ;
|
||||
}
|
||||
nuCurve.vCP = vPtCtrl ;
|
||||
nuCurve.vW = vWeCtrl ;
|
||||
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
||||
NurbsCurveCanonicalize( nuCurve) ;
|
||||
for ( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||
snData.mCP[i][j] = nuCurve.vCP[i] ;
|
||||
}
|
||||
snData.vU = nuCurve.vU ;
|
||||
}
|
||||
snData.bPeriodicU = false ;
|
||||
}
|
||||
if ( snData.bPeriodicV || ! snData.bClampedV) {
|
||||
bool bIsRational = snData.bRat ;
|
||||
// vettore dei nodi
|
||||
DBLVECTOR vV ;
|
||||
int nKnot = (int) snData.vV.size() ;
|
||||
for ( int k = 0 ; k < nKnot ; ++k ) {
|
||||
double dKnot = snData.vV[k] ;
|
||||
vV.push_back( dKnot) ;
|
||||
}
|
||||
for( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||
CNurbsData nuCurve ;
|
||||
nuCurve.bPeriodic = true ;
|
||||
nuCurve.nDeg = snData.nDegV ;
|
||||
nuCurve.vU = vV ;
|
||||
// vettore dei punti di controllo
|
||||
PNTVECTOR vPtCtrl ;
|
||||
// vettore dei pesi
|
||||
DBLVECTOR vWeCtrl ;
|
||||
for ( int j = 0 ; j < snData.nCPV ; ++j ) {
|
||||
if ( bIsRational) {
|
||||
vPtCtrl.push_back( snData.mCP[i][j] / snData.mW[i][j]) ;
|
||||
vWeCtrl.push_back( snData.mW[i][j]) ;
|
||||
}
|
||||
else
|
||||
vPtCtrl.push_back( snData.mCP[i][j]) ;
|
||||
}
|
||||
nuCurve.vCP = vPtCtrl ;
|
||||
nuCurve.vW = vWeCtrl ;
|
||||
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
||||
NurbsCurveCanonicalize( nuCurve) ;
|
||||
for ( int j = 0 ; j < snData.nCPV ; ++j ) {
|
||||
snData.mCP[i][j] = nuCurve.vCP[j] ;
|
||||
}
|
||||
snData.vV = nuCurve.vU ;
|
||||
}
|
||||
snData.bPeriodicV = false ;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ISurf*
|
||||
NurbsToBezierSurface(const SNurbsSurfData& snData)
|
||||
{
|
||||
// la superficie Nurbs deve essere in forma canonica
|
||||
if ( snData.bPeriodicU || snData.bPeriodicV || snData.bExtraKnotes )
|
||||
return nullptr ;
|
||||
// controllo sul numero dei nodi
|
||||
int nU = snData.nCPU + snData.nDegU - 1 ;
|
||||
int nV = snData.nCPV + snData.nDegV - 1 ;
|
||||
// controllo nodi e punti di controllo
|
||||
//if ( nU != int( snData.vU.size()) || nV != int( snData.vV.size()) || snData.nCPU * snData.nCPV != int( snData.vCP.size()))
|
||||
if ( nU != int(snData.vU.size()) || nV != int(snData.vV.size())) {
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
// verifico le condizioni agli estremi sui nodi (i primi nDeg nodi e gli ultimi nDeg nodi devono essere uguali tra loro)
|
||||
bool bOk = true ;
|
||||
// direzione U
|
||||
for ( int i = 1 ; i < snData.nDegU ; ++ i) {
|
||||
if ( abs( snData.vU[i] - snData.vU[0]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
for ( int i = 1 ; i < snData.nDegU ; ++ i) {
|
||||
if ( abs( snData.vU[nU - 1 - i] - snData.vU[nU - 1]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
// direzione V
|
||||
for ( int i = 1 ; i < snData.nDegV ; ++ i) {
|
||||
if ( abs( snData.vV[i] - snData.vV[0]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
for ( int i = 1 ; i < snData.nDegV ; ++ i) {
|
||||
if ( abs( snData.vV[nV - 1 - i] - snData.vV[nV - 1]) >= EPS_ZERO)
|
||||
bOk = false ;
|
||||
}
|
||||
if ( ! bOk)
|
||||
return nullptr ;
|
||||
|
||||
// algoritmo 5.7 del libro "The NURBS book"//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// creazione delle strips nella direzione U ( trasformo le curve iso con U costante in bezier)
|
||||
int a = snData.nDegU - 1 ;
|
||||
int b = snData.nDegU ;
|
||||
int nb = 0 ; // numero di strisce in U ( lunghezza con U costante)
|
||||
vector<Point3d> vCPV( snData.nCPV) ;
|
||||
vector< vector<Point3d>> mBC (snData.nDegU + 1,vCPV ) ;
|
||||
vector< vector<Point3d>> mBC_next (snData.nDegU - 1, vCPV) ;
|
||||
vector< vector<Point3d>> mPC_strip(snData.nDegU + 1, vCPV) ; // matrice che verrà ingrandita e conterrà la superficie metà bezier e metà NURBS
|
||||
DBLVECTOR vV_W( snData.nCPV) ;
|
||||
vector<DBLVECTOR> mW( snData.nDegU + 1, vV_W) ;
|
||||
vector<DBLVECTOR> mW_next( snData.nDegU - 1, vV_W) ;
|
||||
vector<DBLVECTOR> mW_strip( snData.nDegU + 1, vV_W) ;
|
||||
DBLVECTOR vAlpha ;
|
||||
vAlpha.resize( snData.nDegU - 1) ;
|
||||
if ( ! snData.bRat ) {
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i ) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row ) {
|
||||
mBC[i][row] = snData.mCP[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i ) {
|
||||
for (int row = 0 ; row < snData.nCPV ; ++ row) {
|
||||
mW[i][row] = snData.mW[i][row] ;
|
||||
mBC[i][row] = snData.mCP[i][row] * snData.mW[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bRef = false ;
|
||||
while ( snData.nDegU != 1 ? b < nU - 1 : b < nU) { // qui correggo un probabile errore, mettendo nU anziché nCPV, come indicato nell'algoritmo
|
||||
int i = b ;
|
||||
while ( b < nU - 1 && abs( snData.vU[b+1] - snData.vU[b]) < EPS_ZERO)
|
||||
++ b ;
|
||||
int mult = b - i + 1 ;
|
||||
if ( mult < snData.nDegU ) {
|
||||
bRef = true ;
|
||||
// calcolo numeratore e alpha
|
||||
double numer = snData.vU[b] - snData.vU[a] ;
|
||||
for ( int j = snData.nDegU ; j > mult ; -- j)
|
||||
vAlpha[j-mult-1] = numer / ( snData.vU[a+j] - snData.vU[a]) ;
|
||||
int r = snData.nDegU - mult ;
|
||||
for ( int j = 1 ; j <= snData.nDegU - mult ; ++j ) {
|
||||
int save = r - j ;
|
||||
int s = mult + j ;
|
||||
if ( ! snData.bRat ) {
|
||||
for ( int k = snData.nDegU ; k >= s ; --k ) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[k][row] = vAlpha[k-s] * mBC[k][row] + ( 1 - vAlpha[k-s]) * mBC[k-1][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int k = snData.nDegU ; k >= s ; --k ) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[k][row] = vAlpha[k-s] * mBC[k][row] + ( 1 - vAlpha[k-s]) * mBC[k-1][row] ;
|
||||
mW[k][row] = vAlpha[k-s] * mW[k][row] + ( 1 - vAlpha[k-s]) * mW[k-1][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( b < nU - 1 ) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC_next[save][row] = mBC[snData.nDegU][row] ;
|
||||
}
|
||||
if ( snData.bRat )
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mW_next[save][row] = mW[snData.nDegU][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mPC_strip.resize( snData.nDegU * ( nb + 1) + 1 , vCPV) ;
|
||||
mW_strip.resize( snData.nDegU * ( nb + 1) + 1, vV_W) ;
|
||||
if ( ! snData.bRat)
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row ) {
|
||||
mPC_strip[i+ nb * snData.nDegU][row] = mBC[i][row] ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i <= snData.nDegU ; ++i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row ) {
|
||||
mPC_strip[i+ nb * snData.nDegU][row] = mBC[i][row]/mW[i][row] ;
|
||||
mW_strip[i+ nb * snData.nDegU][row] = mW[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
++ nb ;
|
||||
// ho finito di definire la patch di Bezier attuale e passo alla successiva
|
||||
|
||||
// aggiorno mBC con i valori della prossima pezza di Bezier // corrisponde a nb = nb + 1
|
||||
if ( ! snData.bRat){
|
||||
for (int i = 0 ; i < snData.nDegU - 1 ; ++ i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[i][row] = mBC_next[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0 ; i < snData.nDegU - 1 ; ++ i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++row) {
|
||||
mBC[i][row] = mBC_next[i][row] ;
|
||||
mW[i][row] = mW_next[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( b < nU - 1 ) {
|
||||
for ( int i = snData.nDegU - mult ; i <= snData.nDegU ; ++ i) {
|
||||
for (int row = 0 ; row < snData.nCPV ; ++ row ) {
|
||||
mBC[i][row] = snData.mCP[b - snData.nDegU + i + 1][row] ;
|
||||
}
|
||||
}
|
||||
if ( snData.bRat ) {
|
||||
for ( int i = snData.nDegU - mult ; i <= snData.nDegU ; ++ i) {
|
||||
for (int row = 0 ; row < snData.nCPV ; ++ row ) {
|
||||
mW[i][row] = snData.mW[b - snData.nDegU + i + 1][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
a = b ;
|
||||
++b ;
|
||||
}
|
||||
else if ( snData.nDegU == 1 && b < nU) {
|
||||
a = b ;
|
||||
++b ;
|
||||
}
|
||||
}
|
||||
|
||||
// se non ho raffinato allora tutti i nodi avevano gi? molteplicit? massima. Converto direttamente in Bezier la dir U
|
||||
int nCPU_ref ; // numero dei punti di controllo in U dopo il raffinamento
|
||||
if ( ! bRef ) {
|
||||
nCPU_ref = snData.nCPU ;
|
||||
mPC_strip.resize( snData.nCPU, vCPV) ;
|
||||
mW_strip.resize( snData.nCPU, vV_W) ;
|
||||
if ( ! snData.bRat) {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++ row) {
|
||||
mPC_strip[i][row] = snData.mCP[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row < snData.nCPV ; ++ row) {
|
||||
mPC_strip[i][row] = snData.mCP[i][row] ;
|
||||
mW_strip[i][row] = snData.mW[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
nCPU_ref = snData.nDegU * nb + 1 ; // numero dei punti di controllo in U dopo il raffinamento
|
||||
|
||||
// ora ho ottenuto le strisce nDegU x nCPV
|
||||
// devo ripetere la procedura, sulla dir V, per ottenere le patch nDegU x nDegV
|
||||
a = snData.nDegV - 1 ;
|
||||
b = snData.nDegV ;
|
||||
int nc = 0 ; // numero di strisce in V ( lunghezza con V costante)
|
||||
vector<Point3d> vDegV(snData.nDegV + 1) ;
|
||||
vector<Point3d> vDegV_1(snData.nDegV - 1) ;
|
||||
vector< vector<Point3d>> m_BC1( nCPU_ref, vDegV) ;
|
||||
vector< vector<Point3d>> m_BC1_next( nCPU_ref, vDegV_1) ;
|
||||
DBLVECTOR vV1_W(snData.nDegV + 1) ;
|
||||
DBLVECTOR vV2_W(snData.nDegV - 1) ;
|
||||
vector<DBLVECTOR> mW1( nCPU_ref, vV1_W) ;
|
||||
vector<DBLVECTOR> mW1_next( nCPU_ref, vV2_W) ;
|
||||
DBLVECTOR vAlpha1( snData.nDegV - 1) ;
|
||||
vector<vector<Point3d>> mPC_tot( nCPU_ref, vDegV) ;
|
||||
vector<DBLVECTOR> mW_tot( nCPU_ref, vV1_W) ;
|
||||
if ( ! snData.bRat ) {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i ) {
|
||||
for ( int row = 0 ; row <= snData.nDegV ; ++row ) {
|
||||
m_BC1[i][row] = mPC_strip[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i ) {
|
||||
for (int row = 0 ; row <= snData.nDegV ; ++ row) {
|
||||
mW1[i][row] = mW_strip[i][row] ;
|
||||
m_BC1[i][row] = mPC_strip[i][row] * mW_strip[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bRef = false ;
|
||||
while ( snData.nDegV != 1 ? b < nV - 1 : b < nV) { // qui correggo un probabile errore, mettendo nU anziché nCPV, come indicato nell'algoritmo
|
||||
int i = b ;
|
||||
while ( b < nV - 1 && abs( snData.vV[b+1] - snData.vV[b]) < EPS_ZERO)
|
||||
++ b ;
|
||||
int mult = b - i + 1 ;
|
||||
if ( mult < snData.nDegV ) {
|
||||
bRef = true ;
|
||||
// calcolo numeratore e alpha
|
||||
double numer = snData.vV[b] - snData.vV[a] ;
|
||||
for ( int j = snData.nDegV ; j > mult ; -- j)
|
||||
vAlpha1[j-mult-1] = numer / ( snData.vV[a+j] - snData.vV[a]) ;
|
||||
int r = snData.nDegV - mult ;
|
||||
for ( int j = 1 ; j <= snData.nDegV - mult ; ++j ) {
|
||||
int save = r - j ;
|
||||
int s = mult + j ;
|
||||
if ( ! snData.bRat) {
|
||||
for ( int k = 0 ; k < nCPU_ref ; ++k) {
|
||||
for ( int row = snData.nDegV ; row >= s ; --row ) {
|
||||
m_BC1[k][row] = vAlpha1[row-s] * m_BC1[k][row] + ( 1 - vAlpha1[row-s]) * m_BC1[k][row-1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int k = 0 ; k < nCPU_ref ; ++k) {
|
||||
for ( int row = snData.nDegV ; row >= s ; --row ) {
|
||||
m_BC1[k][row] = vAlpha1[row-s] * m_BC1[k][row] + ( 1 - vAlpha1[row-s]) * m_BC1[k][row-1] ;
|
||||
mW1[k][row] = vAlpha1[row-s] * mW1[k][row] + ( 1 - vAlpha1[row-s]) * mW1[k][row-1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( b < nV - 1 ) {
|
||||
if ( !snData.bRat ){
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
m_BC1_next[i][save] = m_BC1[i][snData.nDegV] ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
m_BC1_next[i][save] = m_BC1[i][snData.nDegV] ;
|
||||
mW1_next[i][save] = mW1[i][snData.nDegV] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int nRef = snData.nDegV * ( nc + 1) + 1 ;
|
||||
for ( int k = 0 ; k < nCPU_ref; ++k){
|
||||
mPC_tot[k].resize( nRef) ;
|
||||
mW_tot[k].resize( nRef) ;
|
||||
}
|
||||
if ( ! snData.bRat)
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row <= snData.nDegV ; ++row ) {
|
||||
mPC_tot[i][row + nc * snData.nDegV] = m_BC1[i][row] ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row <= snData.nDegV ; ++row ) {
|
||||
mPC_tot[i][row + nc * snData.nDegV] = m_BC1[i][row]/mW1[i][row] ;
|
||||
mW_tot[i][row + nc * snData.nDegV] = mW1[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
++ nc ;
|
||||
// ho finito di definire la patch di Bezier attuale e passo alla successiva
|
||||
|
||||
// aggiorno mBC con i valori della prossima pezza di Bezier // corrisponde a nc = nc + 1
|
||||
if ( ! snData.bRat){
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i) {
|
||||
for ( int row = 0 ; row < snData.nDegV - 1 ; ++row) {
|
||||
m_BC1[i][row] = m_BC1_next[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i) {
|
||||
for ( int row = 0 ; row < snData.nDegV - 1 ; ++row) {
|
||||
m_BC1[i][row] = m_BC1_next[i][row] ;
|
||||
mW1[i][row] = mW1_next[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( b < nV - 1) {
|
||||
if ( ! snData.bRat) {
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i ) {
|
||||
for ( int row = snData.nDegV - mult ; row <= snData.nDegV ; ++ row) {
|
||||
m_BC1[i][row] = mPC_strip[i][b - snData.nDegV + row + 1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0 ; i < nCPU_ref ; ++ i ) {
|
||||
for ( int row = snData.nDegV - mult ; row <= snData.nDegV ; ++ row) {
|
||||
m_BC1[i][row] = mPC_strip[i][b - snData.nDegV + row + 1] * mW_strip[i][b - snData.nDegV + row + 1] ;
|
||||
mW1[i][row] = mW_strip[i][b - snData.nDegV + row + 1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
a = b ;
|
||||
++b ;
|
||||
}
|
||||
else if ( snData.nDegV == 1 && b < nV) {
|
||||
a = b ;
|
||||
++b ;
|
||||
}
|
||||
}
|
||||
// se non ho raffinato allora aggiungo direttamente alle matrici della superficie totale
|
||||
int nCPV_ref ; // numero dei punti di controllo in V dopo il raffinamento
|
||||
if ( ! bRef) {
|
||||
nCPV_ref = snData.nCPV ;
|
||||
for ( int k = 0 ; k < nCPU_ref ; ++k){
|
||||
mPC_tot[k].resize( snData.nCPV) ;
|
||||
mW_tot[k].resize( snData.nCPV) ;
|
||||
}
|
||||
if ( ! snData.bRat) {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row < nCPV_ref ; ++ row) {
|
||||
mPC_tot[i][row] = mPC_strip[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref ; ++i) {
|
||||
for ( int row = 0 ; row < nCPV_ref ; ++ row) {
|
||||
mPC_tot[i][row] = mPC_strip[i][row] ;
|
||||
mW_tot[i][row] = mW_strip[i][row] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
nCPV_ref = snData.nDegV * nc + 1 ;
|
||||
|
||||
// finalmente setto la superficie di bezier totale divisa in nb patch in U e nc patch in V
|
||||
PtrOwner<ISurfBezier> pSrfBz( CreateSurfBezier()) ;
|
||||
if ( IsNull( pSrfBz))
|
||||
return nullptr ;
|
||||
pSrfBz->Init(snData.nDegU, snData.nDegV, nb, nc, snData.bRat) ;
|
||||
if ( !snData.bRat ) {
|
||||
for ( int i = 0 ; i < nCPU_ref; ++ i) {
|
||||
for (int j = 0 ; j < nCPV_ref; ++j) {
|
||||
pSrfBz->SetControlPoint( i + nCPU_ref * j, mPC_tot[i][j]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0 ; i < nCPU_ref; ++ i) {
|
||||
for (int j = 0 ; j < nCPV_ref; ++j) {
|
||||
pSrfBz->SetControlPoint( i + nCPU_ref * j, mPC_tot[i][j] /*/ mW_tot[i][j]*/, mW_tot[i][j]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Release( pSrfBz) ;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfAux.h Data : 09.08.23 Versione :
|
||||
// Contenuto : Dichiarazione di alcune funzioni di utilità per le superfici.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 09.08.23 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkSurfAux.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//bool IsClosed( const ICurve& crvC) ;
|
||||
//bool IsValidParam( const ICurve& crvC, double dPar, ICurve::Side nSide) ;
|
||||
//bool IsStartParam( const ICurve& crvC, double dPar) ;
|
||||
//bool IsEndParam( const ICurve& crvC, double dPar) ;
|
||||
//bool GetNearestExtremityToPoint( const Point3d& ptP, const ICurve& Curve, bool& bStart) ;
|
||||
//bool MoveParamToAvoidTg( double& dU, ICurve::Side nSide, const ICurve& Curve) ;
|
||||
//bool GetTang( const ICurve& crvC, double dU, ICurve::Side nS, Vector3d& vtTang) ;
|
||||
//bool GetPointTang( const ICurve& crvC, double dU, ICurve::Side nS, Point3d& ptPos, Vector3d& vtTang) ;
|
||||
//bool GetPointDiffGeom( const ICurve& crvC, double dU, ICurve::Side nS, CrvPointDiffGeom& oDiffG) ;
|
||||
//bool ImproveCurveParamAtPoint( double& dU, const Point3d& ptP, const ICurve* pCrv) ;
|
||||
//bool CurveGetAreaXY( const ICurve& crvC, double& dArea) ;
|
||||
//bool CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea) ;
|
||||
//bool CurveDump( const ICurve& crvC, std::string& sOut, bool bMM, const char* szNewLine) ;
|
||||
//bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||
//bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||
+203
-67
@@ -20,6 +20,9 @@
|
||||
#include "Bernstein.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "Tree.h"
|
||||
#include "Triangulate.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
@@ -33,12 +36,13 @@ using namespace std ;
|
||||
GEOOBJ_REGISTER( SRF_BEZIER, NGE_S_BEZ, SurfBezier) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
SurfBezier::SurfBezier(void)
|
||||
SurfBezier::SurfBezier( void)
|
||||
: m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_nDegU(), m_nDegV(), m_nSpanU(), m_nSpanV(), m_bRat( false),
|
||||
m_bTrimmed( false), m_pTrimReg( nullptr)
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -144,6 +148,15 @@ SurfBezier::SetTrimRegion( const ISurfFlatRegion& sfrTrimReg)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
SurfFlatRegion*
|
||||
SurfBezier::GetTrimRegion( void) const
|
||||
{
|
||||
if ( ! m_bTrimmed || m_pTrimReg == nullptr )
|
||||
return nullptr ;
|
||||
return m_pTrimReg ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::GetInfo( int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIsRat, bool& bTrimmed) const
|
||||
@@ -1218,39 +1231,62 @@ SurfBezier::GetCurveOnV( double dU) const
|
||||
CurveComposite*
|
||||
SurfBezier::GetLoop( int nLoop) const
|
||||
{
|
||||
// Se superficie completa, basta concatenare le 4 isoparametriche di bordo
|
||||
if ( ! m_bTrimmed) {
|
||||
// Esiste solo il loop esterno
|
||||
if ( nLoop != 0)
|
||||
// Il primo loop sono le 4 isoparametriche di bordo concatenate
|
||||
if ( ! m_bTrimmed ) {
|
||||
if ( nLoop != 0 )
|
||||
return nullptr ;
|
||||
// Loop
|
||||
// Loop
|
||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||
// prima curva isoparametrica in U con V=0
|
||||
// prima curva isoparametrica in U con V=0
|
||||
PtrOwner<CurveComposite> pCrvCoU0( GetCurveOnU( 0)) ;
|
||||
if ( ! IsNull( pCrvCoU0) && ! pCrvCoU0->IsAPoint())
|
||||
pLoop->AddCurve( Release( pCrvCoU0)) ;
|
||||
// seconda curva isoparametrica in V con U=m_nSpanU
|
||||
// seconda curva isoparametrica in V con U=m_nSpanU
|
||||
PtrOwner<CurveComposite> pCrvCoV1( GetCurveOnV( m_nSpanU)) ;
|
||||
if ( ! IsNull( pCrvCoV1) && ! pCrvCoV1->IsAPoint())
|
||||
pLoop->AddCurve( Release( pCrvCoV1)) ;
|
||||
// terza curva isoparametrica in U con V=m_nSpanV invertita
|
||||
// terza curva isoparametrica in U con V=m_nSpanV invertita
|
||||
PtrOwner<CurveComposite> pCrvCoU1( GetCurveOnU( m_nSpanV)) ;
|
||||
if ( ! IsNull( pCrvCoU1) && ! pCrvCoU1->IsAPoint()) {
|
||||
pCrvCoU1->Invert() ;
|
||||
pLoop->AddCurve( Release( pCrvCoU1)) ;
|
||||
}
|
||||
// quarta curva isoparametrica in V con U=0 invertita
|
||||
// quarta curva isoparametrica in V con U=0 invertita
|
||||
PtrOwner<CurveComposite> pCrvCoV0( GetCurveOnV( 0)) ;
|
||||
if ( ! IsNull( pCrvCoV0) && ! pCrvCoV0->IsAPoint()) {
|
||||
pCrvCoV0->Invert() ;
|
||||
pLoop->AddCurve( Release( pCrvCoV0)) ;
|
||||
}
|
||||
// se loop chiuso lo restituisco, altrimenti errore
|
||||
// se loop chiuso lo restituisco, altrimenti errore
|
||||
return ( pLoop->IsClosed() ? Release( pLoop) : nullptr) ;
|
||||
}
|
||||
// altrimenti trimmata, per ora non gestita
|
||||
else
|
||||
return nullptr ;
|
||||
// la superficie è trimmata, quindi devo cercare nei vari chunck il loop corrispondente
|
||||
else {
|
||||
if ( nLoop > m_pTrimReg->GetChunkCount())
|
||||
return nullptr ;
|
||||
else {
|
||||
int nLoopCount = 0 ;
|
||||
int nChunck = 0, nLoopLoc = 0;
|
||||
INTVECTOR nLoopCountPerChunck ;
|
||||
for ( int i = 0 ; i < m_pTrimReg->GetChunkCount() && nLoopCount != nLoop ; ++ i) {
|
||||
int nLoopCountLoc = 0 ;
|
||||
for ( int j = 0 ; j < m_pTrimReg->GetLoopCount( i) ; ++ j) {
|
||||
++ nLoopCountLoc ;
|
||||
++ nLoopCount ;
|
||||
if ( nLoopCount != nLoop ) {
|
||||
nChunck = i ;
|
||||
nLoopLoc = j ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
nLoopCountPerChunck.push_back( nLoopCountLoc) ;
|
||||
}
|
||||
if ( nLoopCount < nLoop )
|
||||
return nullptr ;
|
||||
PtrOwner<CurveComposite> pLoop( GetBasicCurveComposite( m_pTrimReg->GetLoop( nChunck, nLoopLoc))) ;
|
||||
return Release( pLoop) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1372,6 +1408,82 @@ SurfBezier::GetCurveOnVApproxLen( double dU) const
|
||||
return 0 ;
|
||||
return dLen ;
|
||||
}
|
||||
//
|
||||
////----------------------------------------------------------------------------
|
||||
//const SurfTriMesh*
|
||||
//SurfBezier::GetAuxSurf( void) const
|
||||
//{
|
||||
// // la superficie deve essere validata
|
||||
// if ( m_nStatus != OK) {
|
||||
// ResetAuxSurf() ;
|
||||
// return nullptr ;
|
||||
// }
|
||||
// // se già calcolata, la restituisco
|
||||
// if ( m_pSTM != nullptr)
|
||||
// return m_pSTM ;
|
||||
// // costruttore della superficie
|
||||
// StmFromTriangleSoup stmSoup ;
|
||||
// if ( ! stmSoup.Start())
|
||||
// return nullptr ;
|
||||
// // definisco il numero degli step in U e in V
|
||||
// double dMaxLenU = 0 ;
|
||||
// for ( int j = 0 ; j <= m_nDegV * m_nSpanV ; ++ j)
|
||||
// dMaxLenU = max( dMaxLenU, GetCurveOnUApproxLen( double( j) / m_nDegV)) ;
|
||||
// int nStepU = GetSteps( m_nDegU, m_nSpanU, dMaxLenU, 2) ;
|
||||
// double dMaxLenV = 0 ;
|
||||
// for ( int i = 0 ; i <= m_nDegU * m_nSpanU ; ++ i)
|
||||
// dMaxLenV = max( dMaxLenV, GetCurveOnVApproxLen( double( i) / m_nDegU)) ;
|
||||
// int nStepV = GetSteps( m_nDegV, m_nSpanV, dMaxLenV, 2) ;
|
||||
// // prima curva isoparametrica (potrebbe essere un solo punto)
|
||||
// PolyLine PL1 ;
|
||||
// GetCurveOnU( 0, nStepU, PL1) ;
|
||||
// bool bSingle1 = ( PL1.GetPointNbr() == 1) ;
|
||||
// // ciclo sulle isoparametriche
|
||||
// for ( int i = 1 ; i <= nStepV ; ++ i) {
|
||||
// // seconda curva isoparametrica (con tanti punti quanti la prima, oppure uno solo)
|
||||
// double dV = double( i) * m_nSpanV / nStepV ;
|
||||
// PolyLine PL2 ;
|
||||
// GetCurveOnU( dV, nStepU, PL2) ;
|
||||
// bool bSingle2 = ( PL2.GetPointNbr() == 1) ;
|
||||
// // inserisco i triangoli della striscia nel costruttore della TriMesh
|
||||
// Point3d ptP1c, ptP2c ;
|
||||
// Point3d ptP1n, ptP2n ;
|
||||
// bool bNext = PL1.GetFirstPoint( ptP1c) && PL2.GetFirstPoint( ptP2c) ;
|
||||
// if ( bNext) {
|
||||
// if ( bSingle1 && bSingle2)
|
||||
// bNext = false ;
|
||||
// if ( bSingle1)
|
||||
// ptP1n = ptP1c ;
|
||||
// else
|
||||
// bNext = bNext && PL1.GetNextPoint( ptP1n) ;
|
||||
// if ( bSingle2)
|
||||
// ptP2n = ptP2c ;
|
||||
// else
|
||||
// bNext = bNext && PL2.GetNextPoint( ptP2n) ;
|
||||
// }
|
||||
// while ( bNext) {
|
||||
// // eventuale primo triangolo (con base sui correnti e vertice su P2 successivo)
|
||||
// if ( ! AreSamePointApprox( ptP1c, ptP2c))
|
||||
// stmSoup.AddTriangle( ptP2c, ptP1c, ptP2n) ;
|
||||
// // eventuale secondo triangolo (con vertice su P1 corrente e base sui successivi)
|
||||
// if ( ! AreSamePointApprox( ptP1n, ptP2n))
|
||||
// stmSoup.AddTriangle( ptP1c, ptP1n, ptP2n) ;
|
||||
// // passo alla successiva coppia
|
||||
// ptP1c = ptP1n ;
|
||||
// ptP2c = ptP2n ;
|
||||
// bNext = ( bSingle1 || PL1.GetNextPoint( ptP1n)) && ( bSingle2 || PL2.GetNextPoint( ptP2n)) ;
|
||||
// }
|
||||
// // salvo isoparametrica PL2 in PL1
|
||||
// PL1.GetUPointList().swap( PL2.GetUPointList()) ;
|
||||
// bSingle1 = bSingle2 ;
|
||||
// }
|
||||
// // la completo
|
||||
// if ( ! stmSoup.End())
|
||||
// return nullptr ;
|
||||
// // la salvo
|
||||
// m_pSTM = GetBasicSurfTriMesh( stmSoup.GetSurf()) ;
|
||||
// return m_pSTM ;
|
||||
//}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const SurfTriMesh*
|
||||
@@ -1385,70 +1497,94 @@ SurfBezier::GetAuxSurf( void) const
|
||||
// se già calcolata, la restituisco
|
||||
if ( m_pSTM != nullptr)
|
||||
return m_pSTM ;
|
||||
// costruttore della superficie
|
||||
|
||||
// costruttore della superficie
|
||||
vector<POLYLINEVECTOR> vvPL ;
|
||||
POLYLINEVECTOR vPL ; // per usare i polygon basic
|
||||
Tree Tree( this, true) ;
|
||||
std::vector<std::tuple<Point3d,Point3d>> vTrees ;
|
||||
Tree.GetIndependentTrees( vTrees) ;
|
||||
for ( int i = 0 ; i < (int) vTrees.size() ; ++ i) {
|
||||
Point3d ptMin = std::get<0>( vTrees[i]) ;
|
||||
Point3d ptMax = std::get<1>( vTrees[i]) ;
|
||||
Tree.SetSurf( this, true, ptMin, ptMax) ;
|
||||
//Tree.BuildTree_test() ; // per debug
|
||||
//Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ;
|
||||
Tree.BuildTree( LIN_TOL_FINE, 0.1) ;
|
||||
Tree.GetPolygons( vvPL) ;
|
||||
//Tree.GetPolygonsBasic( vPL) ; // per usare i polygon basic
|
||||
}
|
||||
//// per usare i polygon basic//////////////////////
|
||||
//for (int k = 0 ; k < (int)vPL.size(); ++k) {
|
||||
// vvPL.emplace_back() ;
|
||||
// vvPL.back().push_back(vPL[k]) ;
|
||||
//}
|
||||
//// per usare i polygon basic///////////////////
|
||||
|
||||
PtrOwner<SurfTriMesh> pSrfTm( CreateBasicSurfTriMesh()) ;
|
||||
StmFromTriangleSoup stmSoup ;
|
||||
if ( ! stmSoup.Start())
|
||||
return nullptr ;
|
||||
// definisco il numero degli step in U e in V
|
||||
double dMaxLenU = 0 ;
|
||||
for ( int j = 0 ; j <= m_nDegV * m_nSpanV ; ++ j)
|
||||
dMaxLenU = max( dMaxLenU, GetCurveOnUApproxLen( double( j) / m_nDegV)) ;
|
||||
int nStepU = GetSteps( m_nDegU, m_nSpanU, dMaxLenU, 2) ;
|
||||
double dMaxLenV = 0 ;
|
||||
for ( int i = 0 ; i <= m_nDegU * m_nSpanU ; ++ i)
|
||||
dMaxLenV = max( dMaxLenV, GetCurveOnVApproxLen( double( i) / m_nDegU)) ;
|
||||
int nStepV = GetSteps( m_nDegV, m_nSpanV, dMaxLenV, 2) ;
|
||||
// prima curva isoparametrica (potrebbe essere un solo punto)
|
||||
PolyLine PL1 ;
|
||||
GetCurveOnU( 0, nStepU, PL1) ;
|
||||
bool bSingle1 = ( PL1.GetPointNbr() == 1) ;
|
||||
// ciclo sulle isoparametriche
|
||||
for ( int i = 1 ; i <= nStepV ; ++ i) {
|
||||
// seconda curva isoparametrica (con tanti punti quanti la prima, oppure uno solo)
|
||||
double dV = double( i) * m_nSpanV / nStepV ;
|
||||
PolyLine PL2 ;
|
||||
GetCurveOnU( dV, nStepU, PL2) ;
|
||||
bool bSingle2 = ( PL2.GetPointNbr() == 1) ;
|
||||
// inserisco i triangoli della striscia nel costruttore della TriMesh
|
||||
Point3d ptP1c, ptP2c ;
|
||||
Point3d ptP1n, ptP2n ;
|
||||
bool bNext = PL1.GetFirstPoint( ptP1c) && PL2.GetFirstPoint( ptP2c) ;
|
||||
if ( bNext) {
|
||||
if ( bSingle1 && bSingle2)
|
||||
bNext = false ;
|
||||
if ( bSingle1)
|
||||
ptP1n = ptP1c ;
|
||||
else
|
||||
bNext = bNext && PL1.GetNextPoint( ptP1n) ;
|
||||
if ( bSingle2)
|
||||
ptP2n = ptP2c ;
|
||||
else
|
||||
bNext = bNext && PL2.GetNextPoint( ptP2n) ;
|
||||
|
||||
// prendo i punti di ogni polyline dell'albero, li triangolo e li porto in 3d
|
||||
for ( POLYLINEVECTOR vPL : vvPL) {
|
||||
PNTVECTOR vPnt ;
|
||||
INTVECTOR vTria ;
|
||||
Triangulate Tri ;
|
||||
if ( ! Tri.Make( vPL, vPnt, vTria))
|
||||
return nullptr ;
|
||||
|
||||
// porto i punti in 3d
|
||||
PNTVECTOR vPnt3d ;
|
||||
for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) {
|
||||
Point3d pt3d ;
|
||||
if ( ! GetPointD1D2( vPnt[i].x / SBZ_TREG_COEFF, vPnt[i].y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d))
|
||||
return nullptr ;
|
||||
vPnt3d.push_back( pt3d) ;
|
||||
}
|
||||
while ( bNext) {
|
||||
// eventuale primo triangolo (con base sui correnti e vertice su P2 successivo)
|
||||
if ( ! AreSamePointApprox( ptP1c, ptP2c))
|
||||
stmSoup.AddTriangle( ptP2c, ptP1c, ptP2n) ;
|
||||
// eventuale secondo triangolo (con vertice su P1 corrente e base sui successivi)
|
||||
if ( ! AreSamePointApprox( ptP1n, ptP2n))
|
||||
stmSoup.AddTriangle( ptP1c, ptP1n, ptP2n) ;
|
||||
// passo alla successiva coppia
|
||||
ptP1c = ptP1n ;
|
||||
ptP2c = ptP2n ;
|
||||
bNext = ( bSingle1 || PL1.GetNextPoint( ptP1n)) && ( bSingle2 || PL2.GetNextPoint( ptP2n)) ;
|
||||
int nTria = int( vTria.size()) / 3 ;
|
||||
for ( int i = 0 ; i < nTria ; ++i) {
|
||||
if ( ! stmSoup.AddTriangle( vPnt3d[vTria[3*i]], vPnt3d[vTria[3*i+1]], vPnt3d[vTria[3*i+2]],
|
||||
vPnt[vTria[3*i]].x, vPnt[vTria[3*i]].y,
|
||||
vPnt[vTria[3*i+1]].x, vPnt[vTria[3*i+1]].y,
|
||||
vPnt[vTria[3*i+2]].x, vPnt[vTria[3*i+2]].y))
|
||||
return nullptr ;
|
||||
}
|
||||
// salvo isoparametrica PL2 in PL1
|
||||
PL1.GetUPointList().swap( PL2.GetUPointList()) ;
|
||||
bSingle1 = bSingle2 ;
|
||||
}
|
||||
// la completo
|
||||
}
|
||||
|
||||
// la salvo
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
// la salvo
|
||||
m_pSTM = GetBasicSurfTriMesh( stmSoup.GetSurf()) ;
|
||||
|
||||
return m_pSTM ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::GetLeaves( std::vector<std::tuple<int, Point3d, Point3d>>& vLeaves) const
|
||||
{
|
||||
std::vector<Cell> vCells ;
|
||||
Tree Tree( this, true) ;
|
||||
std::vector<std::tuple<Point3d,Point3d>> vTrees ;
|
||||
Tree.GetIndependentTrees( vTrees) ;
|
||||
for ( int i = 0 ; i < (int) vTrees.size() ; ++ i) {
|
||||
Point3d ptMin = std::get<0>( vTrees[i]) ;
|
||||
Point3d ptMax = std::get<1>( vTrees[i]) ;
|
||||
Tree.SetSurf( this, true, ptMin, ptMax) ;
|
||||
//Tree.BuildTree_test() ;
|
||||
//Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ;
|
||||
Tree.BuildTree( LIN_TOL_FINE, 0.1) ;
|
||||
Tree.GetLeaves( vCells) ;
|
||||
for (int k = 0 ; k < (int)vCells.size(); ++ k ) {
|
||||
std::tuple<int, Point3d, Point3d> tCell ;
|
||||
tCell = make_tuple( vCells[k].m_nId, vCells[k].GetBottomLeft(), vCells[k].GetTopRight()) ;
|
||||
vLeaves.push_back( tCell) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
SurfBezier::ResetAuxSurf( void) const
|
||||
|
||||
+3
-1
@@ -83,6 +83,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
{ return SetControlPoint( GetInd( nIndU, nIndV), ptCtrl, dW) ; }
|
||||
bool SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) override ;
|
||||
bool SetTrimRegion( const ISurfFlatRegion& sfrTrimReg) override ;
|
||||
SurfFlatRegion* GetTrimRegion( void) const override ;
|
||||
bool GetInfo( int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIsRat, bool& bTrimmed) const override ;
|
||||
const Point3d& GetControlPoint( int nIndU, int nIndV, bool* pbOk) const override
|
||||
{ return GetControlPoint( GetInd( nIndU, nIndV), pbOk) ; }
|
||||
@@ -105,6 +106,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
bool GetControlCurveOnU( int nIndV, PolyLine& plCtrlU) const override ;
|
||||
bool GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const override ;
|
||||
const SurfTriMesh* GetAuxSurf( void) const override ;
|
||||
bool GetLeaves( std::vector<std::tuple<int, Point3d, Point3d>>& vLeaves) const override ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
@@ -166,7 +168,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo
|
||||
DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo
|
||||
SurfFlatRegion* m_pTrimReg ; // eventuale regione di trim
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
+128
-85
@@ -66,7 +66,7 @@ SurfTriMesh::Init( int nNumVert, int nNumTria, int nNumFacet)
|
||||
// se superficie vuota
|
||||
if ( nNumVert == 0 && nNumTria == 0 && nNumFacet == 0)
|
||||
return true ;
|
||||
// verifico validità parametri
|
||||
// verifico validit� parametri
|
||||
if ( nNumVert < 3 || nNumTria < 1)
|
||||
return false ;
|
||||
// prealloco la memoria
|
||||
@@ -107,28 +107,32 @@ SurfTriMesh::Clear( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::AddVertex( const Point3d& ptVert)
|
||||
SurfTriMesh::AddVertex( const Point3d& ptVert, const double dU, const double dV)
|
||||
{
|
||||
// imposto ricalcolo
|
||||
// imposto ricalcolo
|
||||
m_nStatus = TO_VERIFY ;
|
||||
m_nParts = - 1 ;
|
||||
m_OGrMgr.Reset() ;
|
||||
ResetHashGrids3d() ;
|
||||
// inserisco il vertice
|
||||
// inserisco il vertice
|
||||
try { m_vVert.emplace_back( ptVert) ;}
|
||||
catch(...) { return SVT_NULL ;}
|
||||
// ne determino l'indice
|
||||
return int( m_vVert.size() - 1) ;
|
||||
int nId = int( m_vVert.size() - 1) ;
|
||||
// aggiugo le coordinate corrispondenti allo spazio parametrico
|
||||
m_vVert[nId].dU = dU ;
|
||||
m_vVert[nId].dV = dV ;
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::MoveVertex( int nInd, const Point3d& ptNewVert)
|
||||
{
|
||||
// verifico validità indice
|
||||
// verifico validit� indice
|
||||
if ( nInd < 0 || nInd >= int( m_vVert.size()))
|
||||
return false ;
|
||||
// verifico non sia già cancellato
|
||||
// verifico non sia gi� cancellato
|
||||
if ( m_vVert[nInd].nIdTria == SVT_DEL)
|
||||
return false ;
|
||||
// sposto il vertice
|
||||
@@ -253,14 +257,14 @@ SurfTriMesh::RemoveTriangle( int nId)
|
||||
// verifico esistenza del triangolo
|
||||
if ( nId < 0 || nId >= GetTriangleSize())
|
||||
return false ;
|
||||
// verifico se già cancellato
|
||||
// verifico se gi� cancellato
|
||||
if ( m_vTria[nId].nIdVert[0] == SVT_DEL)
|
||||
return true ;
|
||||
// aggiorno eventuali riferimenti dei vertici
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
// indice vertice
|
||||
int nV = m_vTria[nId].nIdVert[i] ;
|
||||
// se vertice non c'è passo al prossimo
|
||||
// se vertice non c'� passo al prossimo
|
||||
if ( nV < 0 || nV >= int( m_vVert.size()))
|
||||
continue ;
|
||||
if ( m_vVert[nV].nIdTria == nId) {
|
||||
@@ -278,7 +282,7 @@ SurfTriMesh::RemoveTriangle( int nId)
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
// indice triangolo adiacente
|
||||
int nAdjT = m_vTria[nId].nIdAdjac[i] ;
|
||||
// se triangolo adiacente non c'è passo al prossimo
|
||||
// se triangolo adiacente non c'� passo al prossimo
|
||||
if ( nAdjT == SVT_NULL || m_vTria[nAdjT].nIdVert[0] == SVT_DEL)
|
||||
continue ;
|
||||
// ne sistemo la contro-adiacenza
|
||||
@@ -291,7 +295,7 @@ SurfTriMesh::RemoveTriangle( int nId)
|
||||
m_vTria[nId].nIdVert[0] = SVT_DEL ;
|
||||
// invalido calcolo facce
|
||||
m_bFaceted = false ;
|
||||
// invalido calcolo connettività
|
||||
// invalido calcolo connettivit�
|
||||
m_nParts = - 1 ;
|
||||
return true ;
|
||||
}
|
||||
@@ -357,7 +361,7 @@ SurfTriMesh::GetCentroid( Point3d& ptCen) const
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// se la superficie è chiusa, calcolo il centroide del solido
|
||||
// se la superficie � chiusa, calcolo il centroide del solido
|
||||
if ( IsClosed()) {
|
||||
// applico le formule di R. Nurnberg Imperial College London ad ogni faccia
|
||||
Triangle3d Tria ;
|
||||
@@ -475,6 +479,20 @@ SurfTriMesh::GetVertex( int nId, Point3d& ptP) const
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetVertexParam( int nId, double& dU, double& dV) const
|
||||
{
|
||||
// verifico esistenza del vertice
|
||||
if ( nId < 0 || nId >= GetVertexSize() || m_vVert[nId].nIdTria == SVT_DEL)
|
||||
return false ;
|
||||
// recupero i dati
|
||||
dU = m_vVert[nId].dU ;
|
||||
dV = m_vVert[nId].dV ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetFirstVertex( Point3d& ptP) const
|
||||
@@ -482,6 +500,13 @@ SurfTriMesh::GetFirstVertex( Point3d& ptP) const
|
||||
return GetNextVertex( SVT_NULL, ptP) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetFirstVertexParam( int nId, double& dU, double& dV) const
|
||||
{
|
||||
return GetNextVertexParam( SVT_NULL, dU, dV) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const
|
||||
@@ -499,6 +524,24 @@ SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetNextVertexParam( int nId, double& dU, double& dV) const
|
||||
{
|
||||
// cerco il primo successivo valido
|
||||
do {
|
||||
nId ++ ;
|
||||
} while ( nId < GetVertexSize() && m_vVert[nId].nIdTria == SVT_DEL) ;
|
||||
// se oltrepassata fine
|
||||
if ( nId >= GetVertexSize())
|
||||
return SVT_NULL ;
|
||||
// recupero i dati
|
||||
dU = m_vVert[nId].dU ;
|
||||
dV = m_vVert[nId].dV ;
|
||||
// ritorno indice triangolo corrente
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetTriangle( int nId, int nIdVert[3]) const
|
||||
@@ -731,13 +774,13 @@ SurfTriMesh::GetTriangleBoundaryEdges( int nId, TriFlags3d& TFlags) const
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
// indice triangolo adiacente al lato
|
||||
int nT = m_vTria[nId].nIdAdjac[i] ;
|
||||
// se già definite le facce, verifico indice faccia
|
||||
// se gi� definite le facce, verifico indice faccia
|
||||
if ( m_bFaceted) {
|
||||
TFlags.bFlag[i] = ( nT == SVT_NULL || m_vTria[nId].nIdFacet != m_vTria[nT].nIdFacet) ;
|
||||
}
|
||||
// altrimenti verifico con le normali
|
||||
else
|
||||
// se non c'è triangolo adiacente o se forma un angolo oltre il limite, il lato è un contorno
|
||||
// se non c'� triangolo adiacente o se forma un angolo oltre il limite, il lato � un contorno
|
||||
TFlags.bFlag[i] = ( nT == SVT_NULL || m_vTria[nId].vtN * m_vTria[nT].vtN < m_dCosBndAng) ;
|
||||
}
|
||||
|
||||
@@ -821,7 +864,7 @@ SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
|
||||
if ( nPos == -1)
|
||||
return false ;
|
||||
|
||||
// medio le normali, finché non incontro degli spigoli
|
||||
// medio le normali, finch� non incontro degli spigoli
|
||||
vtN = m_vTria[nT].vtN ;
|
||||
// parto dal triangolo e vado in direzione positiva
|
||||
int nLim = nPos ;
|
||||
@@ -852,7 +895,7 @@ SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
|
||||
SurfTriMesh*
|
||||
SurfTriMesh::CloneTriangle( int nT) const
|
||||
{
|
||||
// verifico validità superficie ed esistenza del triangolo
|
||||
// verifico validit� superficie ed esistenza del triangolo
|
||||
if ( ! IsValid() || nT < 0 || nT >= GetTriangleSize() || m_vTria[nT].nIdVert[0] == SVT_DEL)
|
||||
return nullptr ;
|
||||
|
||||
@@ -959,7 +1002,7 @@ SurfTriMesh::GetLoops( POLYLINEVECTOR& vPL) const
|
||||
if ( ! MarchAlongLoop( nT, 1, m_nTimeStamp, vPL.back()))
|
||||
return false ;
|
||||
}
|
||||
// se il lato 0 è di contorno
|
||||
// se il lato 0 � di contorno
|
||||
else if ( nAdjT[0] == SVT_NULL) {
|
||||
// ho trovato l'inizio di un loop
|
||||
vPL.emplace_back() ;
|
||||
@@ -971,7 +1014,7 @@ SurfTriMesh::GetLoops( POLYLINEVECTOR& vPL) const
|
||||
if ( ! MarchAlongLoop( nT, 1, m_nTimeStamp, vPL.back()))
|
||||
return false ;
|
||||
}
|
||||
// se il lato 1 è di contorno
|
||||
// se il lato 1 � di contorno
|
||||
else if ( nAdjT[1] == SVT_NULL) {
|
||||
// ho trovato l'inizio di un loop
|
||||
vPL.emplace_back() ;
|
||||
@@ -983,7 +1026,7 @@ SurfTriMesh::GetLoops( POLYLINEVECTOR& vPL) const
|
||||
if ( ! MarchAlongLoop( nT, 2, m_nTimeStamp, vPL.back()))
|
||||
return false ;
|
||||
}
|
||||
// se il lato 2 è di contorno
|
||||
// se il lato 2 � di contorno
|
||||
else if ( nAdjT[2] == SVT_NULL) {
|
||||
// ho trovato l'inizio di un loop
|
||||
vPL.emplace_back() ;
|
||||
@@ -995,7 +1038,7 @@ SurfTriMesh::GetLoops( POLYLINEVECTOR& vPL) const
|
||||
if ( ! MarchAlongLoop( nT, 0, m_nTimeStamp, vPL.back()))
|
||||
return false ;
|
||||
}
|
||||
// altrimenti non c'è contorno
|
||||
// altrimenti non c'� contorno
|
||||
else {
|
||||
// marco il triangolo come verificato
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
@@ -1040,10 +1083,10 @@ SurfTriMesh::MarchOneTria( int& nT, int& nV, int nTimeStamp,
|
||||
return false ;
|
||||
// vertice di fine adiacenza e indice del successivo lato
|
||||
int nAdjV = Next( nAdjS) ;
|
||||
// verifico se il lato successivo è un bordo
|
||||
// verifico se il lato successivo � un bordo
|
||||
int nNextT = m_vTria[nAdjT].nIdAdjac[nAdjV] ;
|
||||
if ( nNextT == SVT_NULL) {
|
||||
// se già recuperato
|
||||
// se gi� recuperato
|
||||
if ( m_vTria[nAdjT].nTemp == nTimeStamp) {
|
||||
bEnd = true ;
|
||||
return true ;
|
||||
@@ -1091,8 +1134,8 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR&
|
||||
frOCS.Translate( b3Box.GetMin().z * frOCS.VersZ()) ;
|
||||
|
||||
#if 0
|
||||
// *** 1° Sfruttando le adiacenze ***
|
||||
// Non funziona perchè genera loop con anelli
|
||||
// *** 1� Sfruttando le adiacenze ***
|
||||
// Non funziona perch� genera loop con anelli
|
||||
// Copio la superficie
|
||||
PtrOwner<SurfTriMesh> pStm( Clone()) ;
|
||||
if ( IsNull( pStm))
|
||||
@@ -1100,7 +1143,7 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR&
|
||||
|
||||
// Elimino i triangoli con normale non equiversa alla direzione scelta
|
||||
for ( int i = 0 ; i < int( pStm->m_vTria.size()) ; ++ i) {
|
||||
// se già cancellato, passo oltre
|
||||
// se gi� cancellato, passo oltre
|
||||
if ( pStm->m_vTria[i].nIdVert[0] == SVT_DEL)
|
||||
continue ;
|
||||
// verifico la normale
|
||||
@@ -1159,7 +1202,7 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR&
|
||||
vPL.clear() ;
|
||||
#endif
|
||||
|
||||
// *** 2° Mediante unione delle regioni dei triangoli proiettati ***
|
||||
// *** 2� Mediante unione delle regioni dei triangoli proiettati ***
|
||||
// calcolo la regione dei triangoli proiettati
|
||||
PtrOwner<ISurfFlatRegion> pSfr ;
|
||||
Triangle3d Tria ;
|
||||
@@ -1289,7 +1332,7 @@ SurfTriMesh::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
||||
// segnalo eventuale incongruenza di orientamento
|
||||
if ( ! m_bOriented)
|
||||
sOut += string( "Inconsistent Orientation") + szNewLine ;
|
||||
// segnalo numero di parti se più di una
|
||||
// segnalo numero di parti se pi� di una
|
||||
int nParts = GetPartCount() ;
|
||||
if ( nParts > 1)
|
||||
sOut += string( "Parts =") + ToString( nParts) + szNewLine ;
|
||||
@@ -1519,7 +1562,7 @@ SurfTriMesh::Validate( bool bCorrect)
|
||||
|
||||
// Verifico che i triangoli riferiti dalle facce esistano
|
||||
for ( int i = 0 ; i < GetFacetSize() && m_nStatus == OK && m_bFaceted ; ++ i) {
|
||||
// verifico validità triangolo riferito
|
||||
// verifico validit� triangolo riferito
|
||||
if ( m_vFacet[i] <= SVT_NULL ||
|
||||
m_vFacet[i] >= GetTriangleSize() ||
|
||||
m_vTria[ m_vFacet[i]].nIdVert[0] == SVT_DEL)
|
||||
@@ -1674,7 +1717,7 @@ SurfTriMesh::AdjustAdjacencies( void)
|
||||
bool
|
||||
SurfTriMesh::AdjustOrientations( void)
|
||||
{
|
||||
// se non ci sono almeno 2 triangoli è inutile fare test
|
||||
// se non ci sono almeno 2 triangoli � inutile fare test
|
||||
if ( m_vTria.size() < 2) {
|
||||
m_bOriented = true ;
|
||||
return true ;
|
||||
@@ -1718,7 +1761,7 @@ SurfTriMesh::AdjustTriaOrientation( TRINTDEQUE& S3iQ)
|
||||
S3iQ.pop_front() ;
|
||||
// assegno time stamp al triangolo
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
// se c'è triangolo di riferimento, devo verificare se da invertire
|
||||
// se c'� triangolo di riferimento, devo verificare se da invertire
|
||||
if ( nRefT != SVT_NULL) {
|
||||
// cerco indice half-edge in comune
|
||||
int nE = 0 ;
|
||||
@@ -1736,7 +1779,7 @@ SurfTriMesh::AdjustTriaOrientation( TRINTDEQUE& S3iQ)
|
||||
bool bOk = true ;
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
int nAdjT = m_vTria[nT].nIdAdjac[j] ;
|
||||
// se non c'è adiacenza o va sul triangolo di provenienza
|
||||
// se non c'� adiacenza o va sul triangolo di provenienza
|
||||
if ( nAdjT == SVT_NULL || nAdjT == nRefT)
|
||||
;
|
||||
// la verifico
|
||||
@@ -1791,7 +1834,7 @@ SurfTriMesh::TestSealing( void)
|
||||
bool
|
||||
SurfTriMesh::AdjustTopology( void)
|
||||
{
|
||||
// se non è rimasto alcunché di valido, pulisco tutto ed esco
|
||||
// se non � rimasto alcunch� di valido, pulisco tutto ed esco
|
||||
if ( GetVertexCount() < 3 || GetTriangleCount() < 1) {
|
||||
Clear() ;
|
||||
m_bOriented = true ;
|
||||
@@ -1808,7 +1851,7 @@ SurfTriMesh::AdjustTopology( void)
|
||||
// verifica adiacenze
|
||||
if ( ! AdjustAdjacencies())
|
||||
return false ;
|
||||
// verifica continuità orientazione
|
||||
// verifica continuit� orientazione
|
||||
if ( ! AdjustOrientations())
|
||||
return false ;
|
||||
// verifica chiusura
|
||||
@@ -1846,7 +1889,7 @@ SurfTriMesh::PackVertices( void)
|
||||
vVId.push_back( SVT_DEL) ;
|
||||
}
|
||||
}
|
||||
// se non c'è stata compattazione, esco
|
||||
// se non c'� stata compattazione, esco
|
||||
if ( nFirstFree == SVT_NULL)
|
||||
return true ;
|
||||
// lunghezza vettore indici vertici
|
||||
@@ -1861,7 +1904,7 @@ SurfTriMesh::PackVertices( void)
|
||||
// salto i triangoli cancellati
|
||||
if ( vOId[0] == SVT_DEL)
|
||||
continue ;
|
||||
// verifico la validità degli indici
|
||||
// verifico la validit� degli indici
|
||||
if ( vOId[0] < 0 || vOId[0] >= nVIdSize ||
|
||||
vOId[1] < 0 || vOId[1] >= nVIdSize ||
|
||||
vOId[2] < 0 || vOId[2] >= nVIdSize)
|
||||
@@ -1901,7 +1944,7 @@ SurfTriMesh::PackTriangles( void)
|
||||
vTId.push_back( SVT_DEL) ;
|
||||
}
|
||||
}
|
||||
// se non c'è stata compattazione, esco
|
||||
// se non c'� stata compattazione, esco
|
||||
if ( nFirstFree == SVT_NULL)
|
||||
return true ;
|
||||
// Invalido HashGrid
|
||||
@@ -1915,7 +1958,7 @@ SurfTriMesh::PackTriangles( void)
|
||||
// salto vertice cancellato
|
||||
if ( nOId == SVT_DEL)
|
||||
continue ;
|
||||
// verifico la validità dell'indice
|
||||
// verifico la validit� dell'indice
|
||||
if ( nOId < 0 || nOId >= nTIdSize)
|
||||
return false ;
|
||||
// aggiorno
|
||||
@@ -1945,7 +1988,7 @@ SurfTriMesh::PackTriangles( void)
|
||||
// salto le facets non valide
|
||||
if ( m_vFacet[nId] == SVT_DEL)
|
||||
continue ;
|
||||
// verifico validità indice a triangolo
|
||||
// verifico validit� indice a triangolo
|
||||
if ( m_vFacet[nId] < 0 || m_vFacet[nId] >= nTIdSize)
|
||||
return false ;
|
||||
// aggiorno
|
||||
@@ -2047,7 +2090,7 @@ SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr)
|
||||
m_OGrMgr.Reset() ;
|
||||
ResetHashGrids3d() ;
|
||||
|
||||
// verifico se la polilinea è chiusa
|
||||
// verifico se la polilinea � chiusa
|
||||
bool bClosed = PL.IsClosed() ;
|
||||
|
||||
// costruisco la mesh
|
||||
@@ -2080,7 +2123,7 @@ SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr)
|
||||
}
|
||||
// se curva chiusa, aggiungo gli ultimi due triangoli
|
||||
if ( bClosed) {
|
||||
// non devo aggiungere i vertici, perchè coincidono con quelli iniziali
|
||||
// non devo aggiungere i vertici, perch� coincidono con quelli iniziali
|
||||
// aggiungo i due triangoli relativi
|
||||
nIdV[0] = nV ;
|
||||
nIdV[1] = nV - 1 ;
|
||||
@@ -2099,7 +2142,7 @@ SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr)
|
||||
bool
|
||||
SurfTriMesh::CreateByPointCurve( const Point3d& ptP, const PolyLine& PL)
|
||||
{
|
||||
// verifico validità punto/polilinea
|
||||
// verifico validit� punto/polilinea
|
||||
bool bClosed = PL.IsClosed() ;
|
||||
// se chiusa, la polilinea deve avere almeno 3 punti
|
||||
if ( bClosed) {
|
||||
@@ -2143,7 +2186,7 @@ SurfTriMesh::CreateByPointCurve( const Point3d& ptP, const PolyLine& PL)
|
||||
// aggiorno indice punto precedente su curva
|
||||
nIdV[1] = nIdV[2] ;
|
||||
}
|
||||
// se chiusa aggiungo l'ultimo triangolo (non il vertice perchè è il primo della curva)
|
||||
// se chiusa aggiungo l'ultimo triangolo (non il vertice perch� � il primo della curva)
|
||||
if ( bClosed) {
|
||||
nIdV[2] = 1 ;
|
||||
// inserisco il triangolo A2p -> A1p -> A1s
|
||||
@@ -2235,7 +2278,7 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nR
|
||||
}
|
||||
// ciclo sui punti
|
||||
while ( bNext1 || bNext2) {
|
||||
// se non c'è V2s oppure c'è nuovo V1s e la diagonale più corta è V2p -> V1s
|
||||
// se non c'� V2s oppure c'� nuovo V1s e la diagonale pi� corta � V2p -> V1s
|
||||
if ( ! bNext2 || ( bNext1 && ( nP1s == vPnt2[nP2p].second || vPnt1[nP1s].second == nP2p))) {
|
||||
// inserisco il vertice V1s (se ultimo e curve chiuse, prendo il primo)
|
||||
if ( nP1s == nTotP1 - 1 && bClosed)
|
||||
@@ -2257,7 +2300,7 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nR
|
||||
nV1p = nV1s ; nP1p = nP1s ; ++ nP1s ;
|
||||
bNext1 = ( nP1s < nTotP1) ;
|
||||
}
|
||||
// altrimenti è V1p -> V2s
|
||||
// altrimenti � V1p -> V2s
|
||||
else {
|
||||
// inserisco il vertice V2s (se ultimo e curve chiuse, prendo il primo)
|
||||
if ( nP2s == nTotP2 - 1 && bClosed)
|
||||
@@ -2284,7 +2327,7 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nR
|
||||
|
||||
// altrimenti rigata con parametrizzazione sincrona sulle due curve
|
||||
else {
|
||||
// verifico validità polilinee (devono avere almeno 2 punti e non coincidere se non agli estremi aperti)
|
||||
// verifico validit� polilinee (devono avere almeno 2 punti e non coincidere se non agli estremi aperti)
|
||||
if ( ! VerifyPolylinesForTwoCurves( PL1, PL2))
|
||||
return false ;
|
||||
|
||||
@@ -2409,7 +2452,7 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nR
|
||||
if ( bNext2)
|
||||
dA2s = ( dU2s - dU2F) / dDeltaU2 ;
|
||||
}
|
||||
// se non c'è dA2s oppure c'è nuovo dA1s e la diagonale più corta è dA2p -> dA1s
|
||||
// se non c'� dA2s oppure c'� nuovo dA1s e la diagonale pi� corta � dA2p -> dA1s
|
||||
else if ( ! bNext2 || ( bNext1 && ( dA1s - dA2p) <= ( dA2s - dA1p) + EPS_PARAM)) {
|
||||
// inserisco il vertice A1s
|
||||
if ( ( nV1s = AddVertex( ptP1s)) == SVT_NULL)
|
||||
@@ -2433,7 +2476,7 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nR
|
||||
if ( bNext1)
|
||||
dA1s = ( dU1s - dU1F) / dDeltaU1 ;
|
||||
}
|
||||
// altrimenti è dA1p -> dA2s
|
||||
// altrimenti � dA1p -> dA2s
|
||||
else {
|
||||
// inserisco il vertice A2s
|
||||
if ( ( nV2s = AddVertex( ptP2s)) == SVT_NULL)
|
||||
@@ -2462,7 +2505,7 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nR
|
||||
if ( bClosed) {
|
||||
dA1s = 1 ;
|
||||
dA2s = 1 ;
|
||||
// se la diagonale più corta è dA2p -> dA1s = 0
|
||||
// se la diagonale pi� corta � dA2p -> dA1s = 0
|
||||
if ( ( dA1s - dA2p) <= ( dA2s - dA1p) + EPS_PARAM) {
|
||||
// inserisco il triangolo A2p -> A1p -> A1s = 0
|
||||
nIdV[0] = nV2p ;
|
||||
@@ -2477,7 +2520,7 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nR
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// altrimenti è dA1p -> dA2s = 1
|
||||
// altrimenti � dA1p -> dA2s = 1
|
||||
else {
|
||||
// inserisco il triangolo A2p -> A1p -> A2s = 1
|
||||
nIdV[0] = nV2p ;
|
||||
@@ -2552,7 +2595,7 @@ SurfTriMesh::VerifyPolylinesForTwoCurves( const PolyLine& PL1, const PolyLine& P
|
||||
return false ;
|
||||
// verifiche sui punti successivi (non sugli ultimi)
|
||||
while ( bNext1 || bNext2) {
|
||||
// se c'è nuovo dA1s e la diagonale più corta è dA2p -> dA1s oppure non c'è dA2s
|
||||
// se c'� nuovo dA1s e la diagonale pi� corta � dA2p -> dA1s oppure non c'� dA2s
|
||||
if ( ( bNext1 && ( dA1s - dA2p) <= ( dA2s - dA1p) + EPS_PARAM) || ! bNext2) {
|
||||
// verifico se coincidono
|
||||
if ( AreSamePointApprox( ptP2p, ptP1s))
|
||||
@@ -2563,7 +2606,7 @@ SurfTriMesh::VerifyPolylinesForTwoCurves( const PolyLine& PL1, const PolyLine& P
|
||||
if ( bNext1)
|
||||
dA1s = ( dU1s - dU1F) / dDeltaU1 ;
|
||||
}
|
||||
// altrimenti è dA1p -> dA2s = 1
|
||||
// altrimenti � dA1p -> dA2s = 1
|
||||
else {
|
||||
// verifico se coincidono
|
||||
if ( AreSamePointApprox( ptP1p, ptP2s))
|
||||
@@ -2667,7 +2710,7 @@ AdjustPolylineForRevolution( PolyLine& PL, const Point3d& ptAx, const Vector3d&
|
||||
plTrim.Translate( DIST_SIC * vtTrN) ;
|
||||
PL.Trim( plTrim, false) ;
|
||||
|
||||
// Se polilinea risultante è aperta con estremità molto vicine all'asse le porto su questo
|
||||
// Se polilinea risultante � aperta con estremit� molto vicine all'asse le porto su questo
|
||||
if ( ! PL.IsClosed()) {
|
||||
// verifico l'inizio
|
||||
double dUStart ;
|
||||
@@ -2745,7 +2788,7 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve
|
||||
m_OGrMgr.Reset() ;
|
||||
ResetHashGrids3d() ;
|
||||
|
||||
// verifico se la polilinea è chiusa
|
||||
// verifico se la polilinea � chiusa
|
||||
bool bClosed = MyPL.IsClosed() ;
|
||||
|
||||
// costruisco la mesh
|
||||
@@ -2766,7 +2809,7 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve
|
||||
// verifico se il punto giace sull'asse e vi sta fisso
|
||||
bool bPrevOnAx = bOnlyRev && DistPointLine( ptP, ptAx, vtAx, 1, false).IsSmall() ;
|
||||
int nVPrevOnAx = nV ;
|
||||
// se non è fisso sull'asse, inserisco le copie ruotate
|
||||
// se non � fisso sull'asse, inserisco le copie ruotate
|
||||
if ( ! bPrevOnAx) {
|
||||
for ( int i = 1 ; i <= nStep ; ++i) {
|
||||
ptP.Rotate( ptAx, vtAx, dCosStepRot, dSinStepRot) ;
|
||||
@@ -2788,7 +2831,7 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve
|
||||
bool bOnAx = bOnlyRev && DistPointLine( ptP, ptAx, vtAx, 1, false).IsSmall() ;
|
||||
// ciclo sugli step
|
||||
for ( int i = 1 ; i <= nStep ; ++i) {
|
||||
// se non è fisso sull'asse, inserisco le copie ruotate
|
||||
// se non � fisso sull'asse, inserisco le copie ruotate
|
||||
if ( ! bOnAx) {
|
||||
ptP.Rotate( ptAx, vtAx, dCosStepRot, dSinStepRot) ;
|
||||
if ( ! bOnlyRev)
|
||||
@@ -2797,8 +2840,8 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve
|
||||
return false ;
|
||||
++ nV ;
|
||||
}
|
||||
// per i controlli già fatti non è possibile avere contemp. prec e corr su asse
|
||||
// se il precedente è sull'asse, aggiungo un solo triangolo
|
||||
// per i controlli gi� fatti non � possibile avere contemp. prec e corr su asse
|
||||
// se il precedente � sull'asse, aggiungo un solo triangolo
|
||||
if ( bPrevOnAx) {
|
||||
nIdV[0] = nVPrevOnAx ;
|
||||
nIdV[1] = nV ;
|
||||
@@ -2806,7 +2849,7 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// se il corrente è sull'asse, aggiungo un solo triangolo
|
||||
// se il corrente � sull'asse, aggiungo un solo triangolo
|
||||
else if ( bOnAx) {
|
||||
nIdV[0] = nV - ( nStep + 2) + i ;
|
||||
nIdV[1] = nIdV[0] + 1 ;
|
||||
@@ -2826,8 +2869,8 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve
|
||||
}
|
||||
// se rivoluzione completa, aggiungo i due triangoli di chiusura
|
||||
if ( bFullRev) {
|
||||
// per i controlli già fatti non è possibile avere contemp. prec e corr su asse
|
||||
// se il precedente è sull'asse, aggiungo un solo triangolo
|
||||
// per i controlli gi� fatti non � possibile avere contemp. prec e corr su asse
|
||||
// se il precedente � sull'asse, aggiungo un solo triangolo
|
||||
if ( bPrevOnAx) {
|
||||
nIdV[0] = nVPrevOnAx ;
|
||||
nIdV[1] = nV - nStep ;
|
||||
@@ -2835,7 +2878,7 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
// se il corrente è sull'asse, aggiungo un solo triangolo
|
||||
// se il corrente � sull'asse, aggiungo un solo triangolo
|
||||
else if ( bOnAx) {
|
||||
nIdV[0] = nV - 1 ;
|
||||
nIdV[1] = nV - ( nStep + 1) ;
|
||||
@@ -2858,7 +2901,7 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve
|
||||
// altrimenti ultimo punto di polilinea chiusa
|
||||
if ( bClosed) {
|
||||
for ( int i = 1 ; i <= nStep ; ++i) {
|
||||
// non devo aggiungere i vertici, perchè coincidono con quelli iniziali
|
||||
// non devo aggiungere i vertici, perch� coincidono con quelli iniziali
|
||||
// aggiungo triangolo in basso a sinistra
|
||||
nIdV[0] = nV - nStep + i - 1 ; nIdV[1] = nV - nStep + i ; nIdV[2] = i ;
|
||||
if ( AddTriangle( nIdV) == SVT_NULL)
|
||||
@@ -2894,7 +2937,7 @@ SurfTriMesh::AddBiTriangle( const int nIdVert[4])
|
||||
// | |
|
||||
// 1 -> 2
|
||||
int nIdV[3] ;
|
||||
// se la diagonale 0->2 è uguale o più corta della 1->3
|
||||
// se la diagonale 0->2 � uguale o pi� corta della 1->3
|
||||
if ( SqDist( m_vVert[nIdVert[0]].ptP, m_vVert[nIdVert[2]].ptP) <=
|
||||
SqDist( m_vVert[nIdVert[1]].ptP, m_vVert[nIdVert[3]].ptP) + EPS_SMALL) {
|
||||
// triangolo 0->1->2
|
||||
@@ -2955,14 +2998,14 @@ SurfTriMesh::DoCompacting( double dTol)
|
||||
}
|
||||
// recupero la posizione geometrica del vertice
|
||||
Point3d ptP = m_vVert[nId].ptP ;
|
||||
// se non c'è già un vertice con la stessa posizione lo inserisco nel grid
|
||||
// se non c'� gi� un vertice con la stessa posizione lo inserisco nel grid
|
||||
int nAliasId ;
|
||||
if ( ! VertGrid.Find( ptP, dTol, nAliasId)) {
|
||||
VertGrid.InsertPoint( ptP, nId) ;
|
||||
// salvo l'Id nel vettore di reindirizzo
|
||||
vVId.push_back( nId) ;
|
||||
}
|
||||
// c'è un vertice coincidente
|
||||
// c'� un vertice coincidente
|
||||
else {
|
||||
// salvo l'Id alias nel vettore di reindirizzo
|
||||
vVId.push_back( nAliasId) ;
|
||||
@@ -2981,7 +3024,7 @@ SurfTriMesh::DoCompacting( double dTol)
|
||||
int vOId[3]{ m_vTria[nId].nIdVert[0],
|
||||
m_vTria[nId].nIdVert[1],
|
||||
m_vTria[nId].nIdVert[2]} ;
|
||||
// verifico la validità degli indici
|
||||
// verifico la validit� degli indici
|
||||
if ( vOId[0] < 0 || vOId[0] >= nVIdSize ||
|
||||
vOId[1] < 0 || vOId[1] >= nVIdSize ||
|
||||
vOId[2] < 0 || vOId[2] >= nVIdSize)
|
||||
@@ -2990,7 +3033,7 @@ SurfTriMesh::DoCompacting( double dTol)
|
||||
m_vTria[nId].nIdVert[0] = vVId[vOId[0]] ;
|
||||
m_vTria[nId].nIdVert[1] = vVId[vOId[1]] ;
|
||||
m_vTria[nId].nIdVert[2] = vVId[vOId[2]] ;
|
||||
// se due vertici coincidono o la normale non è calcolabile, cancello il triangolo
|
||||
// se due vertici coincidono o la normale non � calcolabile, cancello il triangolo
|
||||
if ( m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[1] ||
|
||||
m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[2] ||
|
||||
m_vTria[nId].nIdVert[1] == m_vTria[nId].nIdVert[2] ||
|
||||
@@ -3053,7 +3096,7 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther, dou
|
||||
Point3d ptOP = pOther->m_vVert[nOId].ptP ;
|
||||
// la porto nel riferimento della prima superficie
|
||||
ptOP.ToGlob( frOther) ;
|
||||
// se non c'è già un vertice con la stessa posizione lo inserisco
|
||||
// se non c'� gi� un vertice con la stessa posizione lo inserisco
|
||||
int nNewId ;
|
||||
if ( ! VertGrid.Find( ptOP, dTol, nNewId)) {
|
||||
if ( ( nNewId = AddVertex( ptOP)) == SVT_NULL)
|
||||
@@ -3075,7 +3118,7 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther, dou
|
||||
// salto i triangoli cancellati
|
||||
if ( vOId[0] == SVT_DEL)
|
||||
continue ;
|
||||
// verifico la validità degli indici
|
||||
// verifico la validit� degli indici
|
||||
if ( vOId[0] < 0 || vOId[0] >= nVIdSize ||
|
||||
vOId[1] < 0 || vOId[1] >= nVIdSize ||
|
||||
vOId[2] < 0 || vOId[2] >= nVIdSize)
|
||||
@@ -3127,7 +3170,7 @@ SurfTriMesh::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validit� del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
// assegno il box nel riferimento
|
||||
@@ -3172,7 +3215,7 @@ SurfTriMesh::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng,
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dell'asse di rotazione
|
||||
// verifico validit� dell'asse di rotazione
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -3238,7 +3281,7 @@ SurfTriMesh::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double
|
||||
bool bRecalc = ( abs( dCoeffX) < EPS_ZERO || abs( dCoeffY) < EPS_ZERO || abs( dCoeffZ) < EPS_ZERO) ;
|
||||
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
|
||||
if ( m_vTria[i].nIdVert[0] != SVT_DEL) {
|
||||
// se c'è mirror, devo invertire la faccia
|
||||
// se c'� mirror, devo invertire la faccia
|
||||
if ( bMirror)
|
||||
InvertTriangle( i) ;
|
||||
// aggiorno la normale
|
||||
@@ -3260,7 +3303,7 @@ SurfTriMesh::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double
|
||||
bool
|
||||
SurfTriMesh::InvertTriangle( int nT)
|
||||
{
|
||||
// controllo validità triangolo
|
||||
// controllo validit� triangolo
|
||||
if ( ! ExistsTriangle( nT))
|
||||
return true ;
|
||||
// scambio di due vertici
|
||||
@@ -3276,10 +3319,10 @@ SurfTriMesh::InvertTriangle( int nT)
|
||||
bool
|
||||
SurfTriMesh::CalcTriangleNormal( int nT)
|
||||
{
|
||||
// controllo validità triangolo
|
||||
// controllo validit� triangolo
|
||||
if ( m_vTria[nT].nIdVert[0] == SVT_DEL)
|
||||
return true ;
|
||||
// controllo validità vertici riferiti dal triangolo
|
||||
// controllo validit� vertici riferiti dal triangolo
|
||||
if ( m_vTria[nT].nIdVert[0] < 0 ||
|
||||
m_vTria[nT].nIdVert[0] >= GetVertexSize() ||
|
||||
m_vVert[m_vTria[nT].nIdVert[0]].nIdTria == SVT_DEL ||
|
||||
@@ -3308,7 +3351,7 @@ SurfTriMesh::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del piano di specchiatura
|
||||
// verifico validit� del piano di specchiatura
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -3340,7 +3383,7 @@ SurfTriMesh::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d&
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei parametri
|
||||
// verifico validit� dei parametri
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -3371,11 +3414,11 @@ SurfTriMesh::ToGlob( const Frame3d& frRef)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validit� del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
// se frame identit�, non devo fare alcunch�
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
@@ -3405,11 +3448,11 @@ SurfTriMesh::ToLoc( const Frame3d& frRef)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validit� del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
// se frame identit�, non devo fare alcunch�
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
@@ -3439,11 +3482,11 @@ SurfTriMesh::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei frame
|
||||
// verifico validit� dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
// se i due riferimenti coincidono, non devo fare alcunch�
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
@@ -3500,7 +3543,7 @@ SurfTriMesh::ResetHashGrids3d( void) const
|
||||
bool
|
||||
SurfTriMesh::VerifyHashGrids3d( void) const
|
||||
{
|
||||
// se già calcolato, non devo fare altro
|
||||
// se gi� calcolato, non devo fare altro
|
||||
if ( m_pHGrd3d != nullptr)
|
||||
return true ;
|
||||
// alloco
|
||||
@@ -3571,7 +3614,7 @@ SurfTriMesh::VerifyConnection( void) const
|
||||
// ciclo sui triangoli
|
||||
m_nParts = 0 ;
|
||||
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) {
|
||||
// salto triangoli cancellati o già assegnati
|
||||
// salto triangoli cancellati o gi� assegnati
|
||||
if ( m_vTria[i].nIdVert[0] == SVT_DEL ||
|
||||
m_vTria[i].nPart != SVT_NULL)
|
||||
continue ;
|
||||
|
||||
+20
-13
@@ -27,15 +27,19 @@ class SurfFlatRegion ;
|
||||
// Classe Vertice
|
||||
class StmVert
|
||||
{
|
||||
public :
|
||||
StmVert( void) : ptP(), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ) : ptP( ptQ), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), nIdTria( nIdT), nFlag( nF), nTemp( 0) {}
|
||||
public :
|
||||
Point3d ptP ;
|
||||
int nIdTria ;
|
||||
int nFlag ;
|
||||
mutable int nTemp ;
|
||||
public :
|
||||
StmVert( void) : ptP(), dU( -1), dV( -1), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ) : ptP( ptQ), dU( -1), dV( -1), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
|
||||
StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), dU( -1), dV( -1), nIdTria( nIdT), nFlag( nF), nTemp( 0) {}
|
||||
public :
|
||||
Point3d ptP ;
|
||||
double dU ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x 1000) ( nSpanV x 1000)
|
||||
// della sup di Bezier // -1 se non definito
|
||||
double dV ; // parametro riferito alle coordinate del punto nello spazio parametrico ( nSpanU x 1000) ( nSpanV x 1000)
|
||||
// della sup di Bezier // -1 se non definito
|
||||
int nIdTria ;
|
||||
int nFlag ;
|
||||
mutable int nTemp ;
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -215,7 +219,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
{ m_dSmoothAng = std::max( dSmoothAngDeg, EPS_ANG_SMALL) ;
|
||||
m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ;
|
||||
m_OGrMgr.Reset() ; }
|
||||
int AddVertex( const Point3d& ptVert) override ;
|
||||
int AddVertex( const Point3d& ptVert, const double dU = -1 , const double dV = -1) override ;
|
||||
bool MoveVertex( int nInd, const Point3d& ptNewVert) override ;
|
||||
int AddTriangle( const int nIdVert[3], int nTFlag = 0) override ;
|
||||
bool RemoveTriangle( int nId) override ;
|
||||
@@ -244,8 +248,11 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
double GetSmoothAngle( void) const override
|
||||
{ return m_dSmoothAng ; }
|
||||
bool GetVertex( int nId, Point3d& ptP) const override ;
|
||||
bool GetVertexParam( int nId, double& dU, double& dV) const override ;
|
||||
int GetFirstVertex( Point3d& ptP) const override ;
|
||||
int GetFirstVertexParam( int nId, double& dU, double& dV) const override ;
|
||||
int GetNextVertex( int nId, Point3d& ptP) const override ;
|
||||
int GetNextVertexParam( int nId, double& dU, double& dV) const override ;
|
||||
bool GetTriangle( int nId, int nIdVert[3]) const override ;
|
||||
int GetFirstTriangle( int nIdVert[3]) const override ;
|
||||
int GetNextTriangle( int nId, int nIdVert[3]) const override ;
|
||||
@@ -392,14 +399,14 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
double m_dCosBndAng ; // coseno dell'angolo limite per considerare un lato un contorno
|
||||
double m_dSmoothAng ; // angolo limite per mediare le normali (in gradi)
|
||||
double m_dCosSmAng ; // coseno dell'angolo limite per mediare le normali
|
||||
bool m_bOriented ; // la superficie è orientata consistentemente in tutte le sue parti
|
||||
bool m_bOriented ; // la superficie � orientata consistentemente in tutte le sue parti
|
||||
bool m_bClosed ; // la superficie racchiude un volume
|
||||
bool m_bFaceted ; // flag di validità della sfaccettatura
|
||||
bool m_bFaceted ; // flag di validit� della sfaccettatura
|
||||
VERTVECTOR m_vVert ; // vettore dei vertici
|
||||
TRIAVECTOR m_vTria ; // vettore dei triangoli
|
||||
INTVECTOR m_vFacet ; // vettore delle sfaccettature
|
||||
mutable int m_nTimeStamp ; // orologio locale
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
int m_nTempProp[2] ; // vettore propriet� temporanee
|
||||
int m_nMaxTFlag ; // massimo valore dei TFlag dei triangoli
|
||||
mutable int m_nParts ; // numero di parti connesse (-1 se da calcolare)
|
||||
mutable HashGrids3d* m_pHGrd3d ; // Hash Grid 3d nel suo riferimento
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : Tree.h Data : 21.04.23 Versione :
|
||||
// Contenuto : Implementazione della classe Cell di un albero binario Tree.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 21.04.23 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include <map>
|
||||
#include "SurfBezier.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveLine.h"
|
||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||
|
||||
struct Inters {
|
||||
int nIn ;
|
||||
PNTVECTOR vpt ;
|
||||
int nOut ;
|
||||
bool bCCW ;
|
||||
bool bVertex ;
|
||||
int nChunk ;
|
||||
// riordino le intersezioni per lato in senso antiorario dal top
|
||||
// se ho più intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR
|
||||
bool operator < ( Inters& b) {
|
||||
// trovo in che ordine stanno i due strat, tenendo conto anche della possibilità che siano vertici
|
||||
INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6, 3} ;
|
||||
INTVECTOR::iterator iter1 = find( vEdges.begin(), vEdges.end(), nIn) ;
|
||||
int nPos1 = std::distance( vEdges.begin(), iter1) ;
|
||||
INTVECTOR::iterator iter2 = find( vEdges.begin(), vEdges.end(), b.nIn) ;
|
||||
int nPos2 = std::distance( vEdges.begin(), iter2) ;
|
||||
// se sono loop interni li ordino in modo decrescente rispetto all'area
|
||||
bool bEqIn = ( nIn == b.nIn) ;
|
||||
double dAreaA = 0 , dAreaB = 0 ;
|
||||
if ( bEqIn && nIn == -1) {
|
||||
PolyLine pl ;
|
||||
for ( int k = 0 ; k < (int)vpt.size(); ++ k)
|
||||
pl.AddUPoint( k, vpt[k]) ;
|
||||
pl.Close() ;
|
||||
pl.GetAreaXY( dAreaA) ;
|
||||
pl.Clear() ;
|
||||
for ( int k = 0 ; k < (int)b.vpt.size(); ++ k)
|
||||
pl.AddUPoint( k, b.vpt[k]) ;
|
||||
pl.Close() ;
|
||||
pl.GetAreaXY( dAreaB) ;
|
||||
}
|
||||
// se nIn è un vertice sistemo il valore
|
||||
int nEdgeIn = nIn ;
|
||||
if ( nIn > 3)
|
||||
nEdgeIn = nIn - 4 ;
|
||||
return nPos1 < nPos2 ||
|
||||
( bEqIn && nEdgeIn == -1 && abs(dAreaA) > abs(dAreaB)) ||
|
||||
( bEqIn && nEdgeIn == 0 && vpt[0].x > b.vpt[0].x) ||
|
||||
( bEqIn && nEdgeIn == 1 && vpt[0].y > b.vpt[0].y) ||
|
||||
( bEqIn && nEdgeIn == 2 && vpt[0].x < b.vpt[0].x) ||
|
||||
( bEqIn && nEdgeIn == 3 && vpt[0].y < b.vpt[0].y)
|
||||
; }
|
||||
bool operator == ( Inters& b) {
|
||||
return AreSamePointExact( vpt[0], b.vpt[0]) ;
|
||||
}
|
||||
bool operator != ( Inters& b){
|
||||
return ! AreSamePointExact( vpt[0], b.vpt[0]) ;
|
||||
}
|
||||
} ;
|
||||
// nIn e nOut sono flag che indicano da quale lato ho l'ingresso e l'uscita a partire dal lato top in senso antiorario
|
||||
// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario
|
||||
// -1 se la curva è sempre dentro la cella
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class Cell
|
||||
{
|
||||
// Edge 0 ( Top)
|
||||
// Edge 4 ( NW) __________________ Edge 7 ( NE)
|
||||
// | |
|
||||
// | |
|
||||
// Edge 1 ( Left) | | Edge 3 ( Right)
|
||||
// | |
|
||||
// | |
|
||||
// |_________________|
|
||||
// Edge 5 ( SW) Edge 2 (Bottom) Edge 6 ( SE)
|
||||
public :
|
||||
~Cell( void) ;
|
||||
Cell( void) ;
|
||||
Cell( const Point3d& ptBL, const Point3d& ptTR) ;
|
||||
inline bool IsSame( const Cell& cOtherCell) const ;
|
||||
void SetBottomLeft( const Point3d ptBL) { m_ptPbl = ptBL ; }
|
||||
void SetTopRight( const Point3d ptTR) { m_ptPtr = ptTR ; }
|
||||
void SetSplitDirVert( const bool bVert) { m_bSplitVert = bVert ; }
|
||||
void SetParent( const int& nParent) { m_nParent = nParent ; }
|
||||
Point3d GetBottomLeft( void) const { return m_ptPbl ; }
|
||||
Point3d GetTopRight( void) const { return m_ptPtr ; }
|
||||
double GetSplitValue( void) const { return m_dSplit ; }
|
||||
bool IsSplitVert( void) const { return m_bSplitVert ; } // se true la cella verrebbe splittata verticalmente, sennò orizzontalmente
|
||||
bool IsLeaf( void) const ; // flag che indica se la cella ha figli o se è una foglia
|
||||
bool IsProcessed( void) const { return m_bProcessed ; } // flag che indica se tutti i figli della cella, se ce ne sono, sono stati processati
|
||||
void SetProcessed( const bool bProcessed = true) { m_bProcessed = bProcessed ; }
|
||||
static bool minorX ( const Cell& c1, const Cell& c2) { return c1.m_ptPbl.x < c2.m_ptPbl.x ; }
|
||||
static bool minorY ( const Cell& c1, const Cell& c2) { return c1.m_ptPbl.y < c2.m_ptPbl.y ; }
|
||||
|
||||
public :
|
||||
int m_nId ; // Id della cella
|
||||
int m_nTop ; // cella adiacente al lato top
|
||||
int m_nBottom ; // cella adiacente al lato bottom
|
||||
int m_nLeft ; // cella adiacente al lato left
|
||||
int m_nRight ; // cella adiacente al lato right
|
||||
int m_nParent ; // cella genitore
|
||||
int m_nDepth ; // profondità della cella rispetto a root
|
||||
double m_dSplit ; // parametro a cui è stata splittata la cella
|
||||
int m_nChild1 ; // prima cella figlio
|
||||
int m_nChild2 ; // seconda cella figlio
|
||||
int m_nFlag ; // falg che indica la caratterizzazione della cella rispetto ai loop di trim
|
||||
// 0 esterna, 1 intersecata, 2 contiene un loop, 3 intersecata e contenente un loop, 4 contenuta in un loop
|
||||
int m_nFlag2 ; // falg che indica se la cella è stata attraversata durante l'ultima fase del labelling
|
||||
int m_nRightEdgeIn ; // 0 right edge fuori, 1 right edge dentro, 2 metà e metà
|
||||
bool m_bOnLeftEdge ; // flag che indica se la cella è sul lato sinistro ( per superfici chiuse sul parametro U)
|
||||
bool m_bOnTopEdge ; // flag che indica se la cella è sul lato top ( per superfici chiuse sul parametro V)
|
||||
std::vector<Inters> m_vInters ; // vettore delle intersezioni della cella con i loop di trim
|
||||
// ogni elemento del vettore è l'insieme dei punti che caratterizza un atrtaversamento della cella
|
||||
|
||||
private :
|
||||
Point3d m_ptPbl ; // punto bottom left
|
||||
Point3d m_ptPtr ; // punto top right
|
||||
bool m_bProcessed ; // flag che indica se la cella è stata processata
|
||||
bool m_bSplitVert ; // flag che indica in quale direzione è stata divisa la cella
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class Tree
|
||||
{
|
||||
public :
|
||||
~Tree( void) ;
|
||||
Tree( void) ;
|
||||
Tree ( const SurfBezier* pSrfBz, const bool bSplitPatches = true, const Point3d ptMin = ORIG, const Point3d ptMax = ORIG) ;
|
||||
void SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches = true, const Point3d ptMin = ORIG, const Point3d ptMax = ORIG) ;
|
||||
bool GetIndependentTrees( std::vector<std::tuple<Point3d,Point3d>>& vTrees) ; // calcolo la suddivisione della superficie solo sulle singole bbox dei loop di trim ( unendo quelli vicini)
|
||||
bool BuildTree( const double& dLinTol = LIN_TOL_STD, const double& dSideMin = 1, const double& dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh
|
||||
// dSideMin è lunghezza minima del lato di una cella nello spazio reale
|
||||
bool BuildTree_test( const double& dLinTol = LIN_TOL_STD, const double& dSideMin = 1, const double& dSideMax = INFINITO) ;
|
||||
bool GetPolygons( std::vector<POLYLINEVECTOR>& vPolygons) ;
|
||||
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
|
||||
// ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati
|
||||
bool GetLeaves ( std::vector<Cell>& vLeaves) const ;
|
||||
|
||||
private :
|
||||
void Split( const int& nId, const double& dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert
|
||||
void Split( const int& nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert
|
||||
void Balance () ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profonditù di +- 1
|
||||
int GetHeightLeaves ( const int& nId, INTVECTOR& vnLeaves, int d = 0) const ; // altezza del subtree a partire dal nodo nId
|
||||
int GetDepth ( const int& nId, const int& nRef) const ; // livello del nodo nId
|
||||
void GetTopNeigh( const int& nId, INTVECTOR& vTopNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato top
|
||||
void GetBottomNeigh( const int& nId, INTVECTOR& vBottomNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato bottom
|
||||
void GetLeftNeigh( const int& nId, INTVECTOR& vLeftNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato left
|
||||
void GetRightNeigh( const int& nId, INTVECTOR& vRightNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato right
|
||||
void GetRootNeigh( const int& nEdge, INTVECTOR& vNeigh) ; // restituisce le foglie dell'albero che sono adiacenti al lato nEdge, numerato a partire dal top ( 0) in senso antiorario
|
||||
void ResetTree ( void) ; // resetto m_bProcessed a false per tutti i nodi dell'albero
|
||||
INTVECTOR FindCell ( const Point3d& ptToAssign, const CurveLine& cl) const ; // dato un punto, trova la cella foglia a cui appartiene
|
||||
INTVECTOR FindCell ( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells) const ; // dato un punto, trova la cella foglia a cui appartiene
|
||||
bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle
|
||||
bool FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool bFirstInters = true) ; // trova le intersezioni tra una cella e una linea di trim
|
||||
// resituisce l'id della cella verso cui la curva di trim esce e il vettore delle intersezioni per la cella successiva con il primo punto
|
||||
bool CreateCellPolygons ( const int& nLeafId, std::vector<POLYLINEVECTOR>& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell) ;
|
||||
bool CreateIslandAndHoles ( const int& nLeafId, std::vector<POLYLINEVECTOR>& vPolygons, int& nPoly, INTVECTOR& vnParentChunk) ;
|
||||
bool CheckIfBefore( const PolyLine& pl, const int& nEdge) const ;
|
||||
bool CheckIfBefore( const Inters& inA) const ;
|
||||
bool CheckIfBefore( const int& nEdge1, const Point3d& ptP1, const int& nEdge2, const Point3d& ptP2) const ; // punto 1 su edge 1 e punto 2 su edge 2, rispetto al lato 3
|
||||
bool CheckIfBefore( const int& nEdge, const Point3d& ptP1, const Point3d& ptP2, const int& nEdge2 = -1) const ; // entrambi i punti sullo stesso lato, nEdge. nEdge2 serve come backup, in caso nEdge sia un vertice.
|
||||
bool AreSameEdge( const int& nEdge1, const int nEdge2) const ;
|
||||
bool AddVertex( const int& nId, const std::vector<PNTVECTOR>& vEdgeVertex, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd) const ;
|
||||
//bool SetRightEdgeIn( int nId, std::vector<PNTVECTOR>& vEdgeVertex, PolyLine& plTrimmedPoly) ;
|
||||
bool SetRightEdgeIn( const int& nId) ;
|
||||
bool CategorizeCell( const int& nId) ;
|
||||
bool CheckIfBetween( const Inters& inA, const Inters& inB) const ;
|
||||
bool OnWhichEdge( const int& nId, const Point3d& ptToAssign, int& nEdge) const ;
|
||||
|
||||
private :
|
||||
const SurfBezier* m_pSrfBz ; // superficie di bezier
|
||||
DBLVECTOR m_vDim ; // distanze tra i vertici della superficie di bezier in 3d in ordine antiorario a partire da ptP00
|
||||
bool m_bTrimmed ; // superficie trimmata
|
||||
std::vector<INTVECTOR> m_vChunk ; // elenco dei loop divisi per chunk
|
||||
std::map<int,int> m_mChunk ;
|
||||
ICURVEPOVECTOR m_vLoop ; // curve di loop
|
||||
std::vector<std::tuple<PolyLine,bool>> m_vPlApprox ;
|
||||
bool m_bBilinear ; // superficie bilineare
|
||||
bool m_bMulti ; // superficie multi-patch
|
||||
bool m_bClosedU ; // superficie chiusa lungo il parametro U
|
||||
bool m_bClosedV ; // superficie chiusa lungo il parametro V
|
||||
bool m_bSplitPatches ; // flag che indica se le patches sono state divise prima della creazione dell'albero
|
||||
int m_nDegU ; // grado della superficie nel parametro U
|
||||
int m_nDegV ; // grado della superficie nel parametro V
|
||||
int m_nSpanU ;
|
||||
int m_nSpanV ;
|
||||
std::vector<POLYLINEVECTOR> m_vPolygons ; // vettore dei poligoni del tree
|
||||
std::map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root
|
||||
std::map<int,PNTVECTOR> m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id è lo stesso che la cella ha in m_mTree
|
||||
INTVECTOR m_vnLeaves ; // vettore delle foglie
|
||||
INTVECTOR m_vnParents ; // vettore delle celle ottenute dalla divisione preliminare in singole patch
|
||||
} ;
|
||||
Reference in New Issue
Block a user