Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d1cf3f1f2f | |||
| ffa7c3dad5 | |||
| a3502b5c07 | |||
| a9259e8679 | |||
| d3bc7bee64 | |||
| aa82c82ddc | |||
| 8a6dbf044e | |||
| 76d009ddbe | |||
| 6deff01b6e | |||
| e79bb117d2 | |||
| 2ea4b59b9b | |||
| 6e9465247f | |||
| 1d1fb41212 |
+2
-2
@@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "\EgtDev\Include\EGkBBox3d.h"
|
#include "/EgtDev/Include/EGkBBox3d.h"
|
||||||
#include "\EgtDev\Include\EGkFrame3d.h"
|
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|||||||
+1
-1
@@ -3134,7 +3134,7 @@ CurveComposite::RemoveUndercutOnY( double dLinTol, double dAngTolDeg)
|
|||||||
pSfrCut->Translate( b3Box.GetMin() - Point3d( 10 * EPS_SMALL, dLen, 0)) ;
|
pSfrCut->Translate( b3Box.GetMin() - Point3d( 10 * EPS_SMALL, dLen, 0)) ;
|
||||||
// calcolo la classificazione della curva rispetto alla regione
|
// calcolo la classificazione della curva rispetto alla regione
|
||||||
CRVCVECTOR ccClass ;
|
CRVCVECTOR ccClass ;
|
||||||
if ( ! pSfrCut->GetCurveClassification( *pOutLoop, ccClass))
|
if ( ! pSfrCut->GetCurveClassification( *pOutLoop, EPS_SMALL, ccClass))
|
||||||
return false ;
|
return false ;
|
||||||
// determino gli intervalli di curva da conservare
|
// determino gli intervalli di curva da conservare
|
||||||
Intervals inOk ;
|
Intervals inOk ;
|
||||||
|
|||||||
+10
-11
@@ -23,33 +23,30 @@
|
|||||||
bool
|
bool
|
||||||
CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, double dLinTol, MDCVECTOR& vApproxMin)
|
CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, double dLinTol, MDCVECTOR& vApproxMin)
|
||||||
{
|
{
|
||||||
double dSqDist ;
|
|
||||||
double dPar ;
|
|
||||||
double dUIni ;
|
|
||||||
double dUFin ;
|
|
||||||
Point3d ptIni ;
|
|
||||||
Point3d ptFin ;
|
|
||||||
double dMinDist ;
|
|
||||||
double dSqMinDist ;
|
|
||||||
MinDistCalc approxMin ;
|
|
||||||
|
|
||||||
|
vApproxMin.reserve( 4) ;
|
||||||
|
vApproxMin.clear() ;
|
||||||
|
|
||||||
bool bFound = false ;
|
bool bFound = false ;
|
||||||
bool bOnEnd = false ;
|
bool bOnEnd = false ;
|
||||||
vApproxMin.reserve( 4) ;
|
double dUIni, dUFin ;
|
||||||
vApproxMin.clear() ;
|
Point3d ptIni, ptFin ;
|
||||||
|
double dMinDist, dSqMinDist ;
|
||||||
for ( bool bLine = PL.GetFirstULine( &dUIni, &ptIni, &dUFin, &ptFin) ;
|
for ( bool bLine = PL.GetFirstULine( &dUIni, &ptIni, &dUFin, &ptFin) ;
|
||||||
bLine ;
|
bLine ;
|
||||||
bLine = PL.GetNextULine( &dUIni, &ptIni, &dUFin, &ptFin)) {
|
bLine = PL.GetNextULine( &dUIni, &ptIni, &dUFin, &ptFin)) {
|
||||||
// calcolo la distanza del punto dal segmento
|
// calcolo la distanza del punto dal segmento
|
||||||
DistPointLine dstPtLn( ptP, ptIni, ptFin) ;
|
DistPointLine dstPtLn( ptP, ptIni, ptFin) ;
|
||||||
|
double dSqDist ;
|
||||||
if ( ! dstPtLn.GetSqDist( dSqDist))
|
if ( ! dstPtLn.GetSqDist( dSqDist))
|
||||||
continue ;
|
continue ;
|
||||||
// altro punto con la stessa minima distanza già trovata
|
// altro punto con la stessa minima distanza già trovata
|
||||||
if ( bFound && abs( dSqDist - dSqMinDist) < 2 * dMinDist * dLinTol) {
|
if ( bFound && abs( dSqDist - dSqMinDist) < 2 * dMinDist * dLinTol) {
|
||||||
// salvo i dati nella struttura
|
// salvo i dati nella struttura
|
||||||
|
MinDistCalc approxMin ;
|
||||||
approxMin.dDist = dMinDist ;
|
approxMin.dDist = dMinDist ;
|
||||||
dstPtLn.GetMinDistPoint( approxMin.ptQ) ;
|
dstPtLn.GetMinDistPoint( approxMin.ptQ) ;
|
||||||
|
double dPar ;
|
||||||
dstPtLn.GetParamAtMinDistPoint( dPar) ;
|
dstPtLn.GetParamAtMinDistPoint( dPar) ;
|
||||||
approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ;
|
approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ;
|
||||||
approxMin.dParMin = dUIni ;
|
approxMin.dParMin = dUIni ;
|
||||||
@@ -66,8 +63,10 @@ CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, double dLinTol, MDCV
|
|||||||
dSqMinDist = dSqDist ;
|
dSqMinDist = dSqDist ;
|
||||||
dMinDist = sqrt( dSqMinDist) ;
|
dMinDist = sqrt( dSqMinDist) ;
|
||||||
// salvo i dati nella struttura
|
// salvo i dati nella struttura
|
||||||
|
MinDistCalc approxMin ;
|
||||||
approxMin.dDist = dMinDist ;
|
approxMin.dDist = dMinDist ;
|
||||||
dstPtLn.GetMinDistPoint( approxMin.ptQ) ;
|
dstPtLn.GetMinDistPoint( approxMin.ptQ) ;
|
||||||
|
double dPar ;
|
||||||
dstPtLn.GetParamAtMinDistPoint( dPar) ;
|
dstPtLn.GetParamAtMinDistPoint( dPar) ;
|
||||||
approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ;
|
approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ;
|
||||||
approxMin.dParMin = dUIni ;
|
approxMin.dParMin = dUIni ;
|
||||||
|
|||||||
Binary file not shown.
@@ -392,6 +392,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClCompile Include="SurfFlatRegionBooleans.cpp" />
|
<ClCompile Include="SurfFlatRegionBooleans.cpp" />
|
||||||
<ClCompile Include="SurfFlatRegionOffset.cpp" />
|
<ClCompile Include="SurfFlatRegionOffset.cpp" />
|
||||||
<ClCompile Include="SurfTriMeshBooleans.cpp" />
|
<ClCompile Include="SurfTriMeshBooleans.cpp" />
|
||||||
|
<ClCompile Include="SurfTriMeshUtilities.cpp" />
|
||||||
<ClCompile Include="TextureData.cpp" />
|
<ClCompile Include="TextureData.cpp" />
|
||||||
<ClCompile Include="Tool.cpp" />
|
<ClCompile Include="Tool.cpp" />
|
||||||
<ClCompile Include="UserObjDefault.cpp" />
|
<ClCompile Include="UserObjDefault.cpp" />
|
||||||
|
|||||||
@@ -453,6 +453,9 @@
|
|||||||
<ClCompile Include="CDeRectPrismoidTria.cpp">
|
<ClCompile Include="CDeRectPrismoidTria.cpp">
|
||||||
<Filter>File di origine\GeoCollision</Filter>
|
<Filter>File di origine\GeoCollision</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="SurfTriMeshUtilities.cpp">
|
||||||
|
<Filter>File di origine\Geo</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="stdafx.h">
|
<ClInclude Include="stdafx.h">
|
||||||
|
|||||||
+1
-1
@@ -7647,7 +7647,7 @@ GdbExecutor::CurveCopyBySplitClass( const STRVECTOR& vsParams)
|
|||||||
IntersCurveCurve intCC( *pCrv, *pCloCrv, true) ;
|
IntersCurveCurve intCC( *pCrv, *pCloCrv, true) ;
|
||||||
// recupero la classificazione della prima curva
|
// recupero la classificazione della prima curva
|
||||||
CRVCVECTOR ccClass ;
|
CRVCVECTOR ccClass ;
|
||||||
if ( ! intCC.GetCurveClassification( 0, ccClass))
|
if ( ! intCC.GetCurveClassification( 0, EPS_SMALL, ccClass))
|
||||||
return false ;
|
return false ;
|
||||||
// recupero gli indici dei gruppi destinazione e i loro riferimenti
|
// recupero gli indici dei gruppi destinazione e i loro riferimenti
|
||||||
const int N_GRP = 4 ;
|
const int N_GRP = 4 ;
|
||||||
|
|||||||
+10
-8
@@ -391,7 +391,7 @@ IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
|
IntersCurveCurve::GetCurveClassification( int nCrv, double dLenMin, CRVCVECTOR& ccClass)
|
||||||
{
|
{
|
||||||
// pulisco vettore classificazioni
|
// pulisco vettore classificazioni
|
||||||
ccClass.clear() ;
|
ccClass.clear() ;
|
||||||
@@ -407,7 +407,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
|
|||||||
return false ;
|
return false ;
|
||||||
// se esiste almeno una intersezione
|
// se esiste almeno una intersezione
|
||||||
if ( m_nIntersCount >= 1)
|
if ( m_nIntersCount >= 1)
|
||||||
return CalcCurveClassification( m_pCurve[0], m_Info, ccClass) ;
|
return CalcCurveClassification( m_pCurve[0], m_Info, dLenMin, ccClass) ;
|
||||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||||
else
|
else
|
||||||
return CalcCurveInOrOut( m_pCurve[0], m_pCurve[1], ccClass) ;
|
return CalcCurveInOrOut( m_pCurve[0], m_pCurve[1], ccClass) ;
|
||||||
@@ -424,7 +424,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
|
|||||||
SwapInfoAB( InfoTmp, 1) ;
|
SwapInfoAB( InfoTmp, 1) ;
|
||||||
// se esiste almeno una intersezione
|
// se esiste almeno una intersezione
|
||||||
if ( m_nIntersCount >= 1)
|
if ( m_nIntersCount >= 1)
|
||||||
return CalcCurveClassification( m_pCurve[1], InfoTmp, ccClass) ;
|
return CalcCurveClassification( m_pCurve[1], InfoTmp, dLenMin, ccClass) ;
|
||||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||||
else
|
else
|
||||||
return CalcCurveInOrOut( m_pCurve[1], m_pCurve[0], ccClass) ;
|
return CalcCurveInOrOut( m_pCurve[1], m_pCurve[0], ccClass) ;
|
||||||
@@ -461,7 +461,7 @@ IntersCurveCurve::SwapInfoAB( ICCIVECTOR& Info, int IndCrvOrd)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTOR& Info, CRVCVECTOR& ccClass)
|
IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTOR& Info, double dLenMin, CRVCVECTOR& ccClass)
|
||||||
{
|
{
|
||||||
// numero intersezioni
|
// numero intersezioni
|
||||||
int nNumInters = int( Info.size()) ;
|
int nNumInters = int( Info.size()) ;
|
||||||
@@ -471,6 +471,8 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
|||||||
double dStartPar, dEndPar ;
|
double dStartPar, dEndPar ;
|
||||||
if ( pCurve == nullptr || ! pCurve->GetDomain( dStartPar, dEndPar))
|
if ( pCurve == nullptr || ! pCurve->GetDomain( dStartPar, dEndPar))
|
||||||
return false ;
|
return false ;
|
||||||
|
// limito lunghezza minima
|
||||||
|
dLenMin = max( dLenMin, EPS_ZERO) ;
|
||||||
// elimino intersezioni senza attraversamento che giacciono in intervalli di sovrapposizione
|
// elimino intersezioni senza attraversamento che giacciono in intervalli di sovrapposizione
|
||||||
ICCIVECTOR InfoCorr ;
|
ICCIVECTOR InfoCorr ;
|
||||||
InfoCorr.reserve( Info.size()) ;
|
InfoCorr.reserve( Info.size()) ;
|
||||||
@@ -527,7 +529,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
|||||||
for ( int i = 0 ; i < nNumInters ; ++ i) {
|
for ( int i = 0 ; i < nNumInters ; ++ i) {
|
||||||
// se è definito un tratto precedente
|
// se è definito un tratto precedente
|
||||||
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ;
|
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ;
|
||||||
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > EPS_SMALL) {
|
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
|
||||||
// verifico che la definizione sul tratto sia omogenea e valida
|
// verifico che la definizione sul tratto sia omogenea e valida
|
||||||
int nPrevTy = InfoCorr[i].IciA[0].nPrevTy ;
|
int nPrevTy = InfoCorr[i].IciA[0].nPrevTy ;
|
||||||
if ( ( nLastTy != ICCT_NULL && nPrevTy != nLastTy) ||
|
if ( ( nLastTy != ICCT_NULL && nPrevTy != nLastTy) ||
|
||||||
@@ -562,7 +564,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// eventuale tratto finale rimasto
|
// eventuale tratto finale rimasto
|
||||||
if ( dCurrPar < dEndPar - EPS_PARAM && dEndLen - dCurrLen > EPS_SMALL) {
|
if ( dCurrPar < dEndPar - EPS_PARAM && dEndLen - dCurrLen > dLenMin) {
|
||||||
// verifico che la definizione sul tratto sia valida
|
// verifico che la definizione sul tratto sia valida
|
||||||
if ( nLastTy == ICCT_NULL || nLastTy == ICCT_ON)
|
if ( nLastTy == ICCT_NULL || nLastTy == ICCT_ON)
|
||||||
return false ;
|
return false ;
|
||||||
@@ -673,7 +675,7 @@ IntersCurveCurve::GetRegionCurveClassification( void)
|
|||||||
{
|
{
|
||||||
// classifico la prima curva rispetto alla seconda
|
// classifico la prima curva rispetto alla seconda
|
||||||
CRVCVECTOR ccClass ;
|
CRVCVECTOR ccClass ;
|
||||||
if ( ! GetCurveClassification( 0, ccClass))
|
if ( ! GetCurveClassification( 0, EPS_SMALL, ccClass))
|
||||||
return CCREGC_NULL ;
|
return CCREGC_NULL ;
|
||||||
// derivo la classificazione delle curve come regioni
|
// derivo la classificazione delle curve come regioni
|
||||||
bool bIn = false ;
|
bool bIn = false ;
|
||||||
@@ -710,7 +712,7 @@ IntersCurveCurve::GetRegionCurveClassification( void)
|
|||||||
if ( bOnP)
|
if ( bOnP)
|
||||||
return CCREGC_IN2 ;
|
return CCREGC_IN2 ;
|
||||||
CRVCVECTOR ccClass2 ;
|
CRVCVECTOR ccClass2 ;
|
||||||
if ( ! GetCurveClassification( 1, ccClass2) || ccClass2.empty())
|
if ( ! GetCurveClassification( 1, EPS_SMALL, ccClass2) || ccClass2.empty())
|
||||||
return CCREGC_NULL ;
|
return CCREGC_NULL ;
|
||||||
if ( ccClass2[0].nClass == CRVC_OUT)
|
if ( ccClass2[0].nClass == CRVC_OUT)
|
||||||
return CCREGC_OUT ;
|
return CCREGC_OUT ;
|
||||||
|
|||||||
+14
-3
@@ -68,9 +68,20 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
{
|
{
|
||||||
// pulisco tutto
|
// pulisco tutto
|
||||||
Reset() ;
|
Reset() ;
|
||||||
|
// verifico se la curva è un segmento di retta
|
||||||
|
bool bIsLine = false ;
|
||||||
|
const CurveLine* pLine = GetBasicCurveLine( pCrv) ;
|
||||||
|
if ( pLine != nullptr)
|
||||||
|
bIsLine = true ;
|
||||||
|
else {
|
||||||
|
const CurveComposite* pCompo = GetBasicCurveComposite( pCrv) ;
|
||||||
|
Point3d ptStart, ptEnd ;
|
||||||
|
if ( pCompo != nullptr && pCompo->IsALine( 10 * EPS_SMALL, ptStart, ptEnd))
|
||||||
|
bIsLine = true ;
|
||||||
|
}
|
||||||
// verifico che la curva esista e sia piana
|
// verifico che la curva esista e sia piana
|
||||||
Plane3d plPlane ;
|
Plane3d plPlane ;
|
||||||
if ( pCrv == nullptr || ! pCrv->IsFlat( plPlane, false, 10 * EPS_SMALL))
|
if ( pCrv == nullptr || ! pCrv->IsFlat( plPlane, bIsLine, 10 * EPS_SMALL))
|
||||||
return false ;
|
return false ;
|
||||||
// recupero o assegno estrusione
|
// recupero o assegno estrusione
|
||||||
Vector3d vtExtr ;
|
Vector3d vtExtr ;
|
||||||
@@ -449,7 +460,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
inOk.Set( dStart, dEnd) ;
|
inOk.Set( dStart, dEnd) ;
|
||||||
IntersCurveCurve ccInt( *pCrv, *pCircS) ;
|
IntersCurveCurve ccInt( *pCrv, *pCircS) ;
|
||||||
CRVCVECTOR ccPart ;
|
CRVCVECTOR ccPart ;
|
||||||
if ( ! ccInt.GetCurveClassification( 0, ccPart))
|
if ( ! ccInt.GetCurveClassification( 0, EPS_SMALL, ccPart))
|
||||||
return false ;
|
return false ;
|
||||||
for ( auto& ccOne : ccPart) {
|
for ( auto& ccOne : ccPart) {
|
||||||
switch ( ccOne.nClass) {
|
switch ( ccOne.nClass) {
|
||||||
@@ -498,7 +509,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
inOk.Set( dStart, dEnd) ;
|
inOk.Set( dStart, dEnd) ;
|
||||||
IntersCurveCurve ccInt( *pCrv, *pCircE) ;
|
IntersCurveCurve ccInt( *pCrv, *pCircE) ;
|
||||||
CRVCVECTOR ccPart ;
|
CRVCVECTOR ccPart ;
|
||||||
if ( ! ccInt.GetCurveClassification( 0, ccPart))
|
if ( ! ccInt.GetCurveClassification( 0, EPS_SMALL, ccPart))
|
||||||
return false ;
|
return false ;
|
||||||
for ( auto& ccOne : ccPart) {
|
for ( auto& ccOne : ccPart) {
|
||||||
switch ( ccOne.nClass) {
|
switch ( ccOne.nClass) {
|
||||||
|
|||||||
+223
-5
@@ -22,6 +22,7 @@
|
|||||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||||
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
@@ -829,12 +830,11 @@ PolyLine::MyChangeStart( int nPos)
|
|||||||
// solo per polilinee chiuse
|
// solo per polilinee chiuse
|
||||||
if ( ! IsClosed())
|
if ( ! IsClosed())
|
||||||
return false ;
|
return false ;
|
||||||
// cancello ultimo punto ( coincide con primo)
|
// cancello l'ultimo punto ( coincide con il primo)
|
||||||
m_lUPoints.pop_back() ;
|
m_lUPoints.pop_back() ;
|
||||||
// sposto la metà iniziale dei punti alla fine
|
// sposto la parte iniziale dei punti alla fine
|
||||||
for ( int i = 0 ; i < nPos ; ++ i)
|
m_lUPoints.splice( m_lUPoints.end(), m_lUPoints, m_lUPoints.begin(), next( m_lUPoints.begin(), nPos)) ;
|
||||||
m_lUPoints.splice( m_lUPoints.end(), m_lUPoints, m_lUPoints.begin()) ;
|
// aggiungo il punto finale come copia dell'iniziale
|
||||||
// aggiungo punto finale come copia dell'iniziale
|
|
||||||
m_lUPoints.push_back( m_lUPoints.front()) ;
|
m_lUPoints.push_back( m_lUPoints.front()) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
@@ -1296,3 +1296,221 @@ PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut)
|
|||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
DistPointPolyLine( const Point3d& ptP, const PolyLine& plPoly, double& dDist)
|
||||||
|
{
|
||||||
|
// La polilinea deve contenere almeno due punti
|
||||||
|
if ( plPoly.GetPointNbr() < 2)
|
||||||
|
return false ;
|
||||||
|
// Ciclo sui punti della polilinea
|
||||||
|
dDist = INFINITO ;
|
||||||
|
Point3d ptStart, ptEnd ;
|
||||||
|
plPoly.GetFirstPoint( ptStart) ;
|
||||||
|
while ( plPoly.GetNextPoint( ptEnd)) {
|
||||||
|
// distanza del punto dal segmento della polilinea
|
||||||
|
DistPointLine PointLineDistCalc( ptP, ptStart, ptEnd) ;
|
||||||
|
double dPlDist ;
|
||||||
|
PointLineDistCalc.GetDist( dPlDist) ;
|
||||||
|
if ( dPlDist < dDist)
|
||||||
|
dDist = dPlDist ;
|
||||||
|
// assegno nuovo inizio
|
||||||
|
ptStart = ptEnd ;
|
||||||
|
}
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler)
|
||||||
|
{
|
||||||
|
// La polilinea deve essere chiusa e piatta, altrimenti non ha senso parlare di interno
|
||||||
|
Plane3d plPlane ;
|
||||||
|
double dArea ;
|
||||||
|
if ( ! plPoly.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL))
|
||||||
|
return false ;
|
||||||
|
// Impongo l'orientamento CCW
|
||||||
|
if ( dArea < 0)
|
||||||
|
plPlane.Invert() ;
|
||||||
|
// Il punto deve giacere nel piano della polilinea
|
||||||
|
if ( ! PointInPlaneEpsilon( ptP, plPlane, 10 * EPS_SMALL))
|
||||||
|
return false ;
|
||||||
|
// Riferimento alla lista dei punti
|
||||||
|
PNTULIST& List = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
||||||
|
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||||
|
double dMinSqDist = SQ_INFINITO ;
|
||||||
|
Point3d ptMinDist ;
|
||||||
|
auto itMinDistEnd = List.end() ;
|
||||||
|
auto itStart = List.begin() ;
|
||||||
|
auto itEnd = next( itStart) ;
|
||||||
|
for ( ; itEnd != List.end() ; ++ itStart, ++ itEnd) {
|
||||||
|
// Distanza del punto dal segmento corrente
|
||||||
|
DistPointLine dDistCalc( ptP, itStart->first, itEnd->first) ;
|
||||||
|
double dSqDist ;
|
||||||
|
if ( dDistCalc.GetSqDist( dSqDist) && dSqDist < dMinSqDist) {
|
||||||
|
dMinSqDist = dSqDist ;
|
||||||
|
dDistCalc.GetMinDistPoint( ptMinDist) ;
|
||||||
|
itMinDistEnd = itEnd ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Determino tangente di riferimento
|
||||||
|
Vector3d vtTang ;
|
||||||
|
// se minima distanza nell'estremo iniziale del segmento
|
||||||
|
if ( AreSamePointApprox( ptMinDist, prev( itMinDistEnd)->first)) {
|
||||||
|
// direzione del segmento
|
||||||
|
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||||
|
vtCurrTg.Normalize() ;
|
||||||
|
// direzione del segmento precedente
|
||||||
|
Vector3d vtPrevTg ;
|
||||||
|
if ( prev( itMinDistEnd) != List.begin())
|
||||||
|
vtPrevTg = prev( itMinDistEnd)->first - prev( itMinDistEnd, 2)->first ;
|
||||||
|
else
|
||||||
|
vtPrevTg = prev( itMinDistEnd)->first - prev( List.rbegin())->first ;
|
||||||
|
vtPrevTg.Normalize() ;
|
||||||
|
// tangente media
|
||||||
|
vtTang = vtPrevTg + vtCurrTg ;
|
||||||
|
vtTang.Normalize() ;
|
||||||
|
}
|
||||||
|
// se altrimenti minima distanza nell'estremo finale del segmento
|
||||||
|
else if ( AreSamePointApprox( ptMinDist, itMinDistEnd->first)) {
|
||||||
|
// direzione del segmento
|
||||||
|
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||||
|
vtCurrTg.Normalize() ;
|
||||||
|
// direzione del segmento successivo
|
||||||
|
Vector3d vtNextTg ;
|
||||||
|
if ( next( itMinDistEnd) != List.end())
|
||||||
|
vtNextTg = next( itMinDistEnd)->first - itMinDistEnd->first ;
|
||||||
|
else
|
||||||
|
vtNextTg = next( List.begin())->first - itMinDistEnd->first ;
|
||||||
|
vtNextTg.Normalize() ;
|
||||||
|
// tangente media
|
||||||
|
vtTang = vtCurrTg + vtNextTg ;
|
||||||
|
vtTang.Normalize() ;
|
||||||
|
}
|
||||||
|
// altrimenti minima distanza con l'interno
|
||||||
|
else {
|
||||||
|
vtTang = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||||
|
}
|
||||||
|
// Determino la posizione del punto
|
||||||
|
Vector3d vtDiff = ptP - ptMinDist ;
|
||||||
|
Vector3d vtOut = vtTang ^ plPlane.GetVersN() ;
|
||||||
|
vtOut.Normalize() ;
|
||||||
|
return ( vtDiff * vtOut < -dToler) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
GetPointParamOnPolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler, double& dPar)
|
||||||
|
{
|
||||||
|
// La polilinea deve contenere almeno due punti
|
||||||
|
if ( plPoly.GetPointNbr() < 2)
|
||||||
|
return false ;
|
||||||
|
// Ciclo sui punti della polilinea
|
||||||
|
int nSeg = -1 ;
|
||||||
|
double dMinSqDist = SQ_INFINITO ;
|
||||||
|
double dMinPar = -1 ;
|
||||||
|
Point3d ptStart, ptEnd ;
|
||||||
|
plPoly.GetFirstPoint( ptStart) ;
|
||||||
|
while ( plPoly.GetNextPoint( ptEnd)) {
|
||||||
|
// aggiorno l'indice
|
||||||
|
++ nSeg ;
|
||||||
|
// distanza del punto dal segmento della polilinea
|
||||||
|
DistPointLine dDistCalc( ptP, ptStart, ptEnd) ;
|
||||||
|
double dSqDist ;
|
||||||
|
if ( dDistCalc.GetSqDist( dSqDist) && dSqDist < dMinSqDist) {
|
||||||
|
dMinSqDist = dSqDist ;
|
||||||
|
double dSegPar ;
|
||||||
|
dDistCalc.GetParamAtMinDistPoint( dSegPar) ;
|
||||||
|
dMinPar = nSeg + dSegPar ;
|
||||||
|
}
|
||||||
|
// assegno nuovo inizio
|
||||||
|
ptStart = ptEnd ;
|
||||||
|
}
|
||||||
|
// Il punto è sulla linea se la sua distanza rispetta la tolleranza
|
||||||
|
return ( dMinSqDist < dToler * dToler) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
ChangePolyLineStart( PolyLine& plPoly, const Point3d& ptNewStart, double dToler)
|
||||||
|
{
|
||||||
|
// La polilinea deve essere chiusa
|
||||||
|
if ( ! plPoly.IsClosed())
|
||||||
|
return false ;
|
||||||
|
// Riferimento alla lista dei punti
|
||||||
|
PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
||||||
|
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||||
|
double dMinSqDist = SQ_INFINITO ;
|
||||||
|
auto itMinDistEnd = LoopList.end() ;
|
||||||
|
auto itStart = LoopList.begin() ;
|
||||||
|
auto itEnd = next( itStart) ;
|
||||||
|
for ( ; itEnd != LoopList.end() ; ++ itStart, ++ itEnd) {
|
||||||
|
// Distanza del punto dal segmento corrente
|
||||||
|
DistPointLine dDistCalc( ptNewStart, itStart->first, itEnd->first) ;
|
||||||
|
double dSqDist ;
|
||||||
|
if ( dDistCalc.GetSqDist( dSqDist) && dSqDist < dMinSqDist) {
|
||||||
|
dMinSqDist = dSqDist ;
|
||||||
|
itMinDistEnd = itEnd ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Se il punto non sta sulla polilinea, non ha senso cambiare l'inizio
|
||||||
|
if ( dMinSqDist > dToler * dToler)
|
||||||
|
return false ;
|
||||||
|
// Se il punto non coincide con un vertice, lo aggiungo
|
||||||
|
auto itNewStart = LoopList.end() ;
|
||||||
|
if ( AreSamePointApprox( ptNewStart, prev( itMinDistEnd)->first))
|
||||||
|
itNewStart = prev( itMinDistEnd) ;
|
||||||
|
else if ( AreSamePointApprox( ptNewStart, itMinDistEnd->first))
|
||||||
|
itNewStart = itMinDistEnd ;
|
||||||
|
else
|
||||||
|
itNewStart = LoopList.emplace( itMinDistEnd, ptNewStart, 0) ;
|
||||||
|
// Cancello l'ultimo punto ( coincide con il primo)
|
||||||
|
LoopList.pop_back() ;
|
||||||
|
// Sposto la parte iniziale dei punti alla fine
|
||||||
|
LoopList.splice( LoopList.end(), LoopList, LoopList.begin(), itNewStart) ;
|
||||||
|
// Aggiungo il punto finale come copia dell'iniziale
|
||||||
|
LoopList.push_back( LoopList.front()) ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SplitPolyLineAtPoint( const PolyLine& plPoly, const Point3d& ptP, double dToler, PolyLine& plPoly1, PolyLine& plPoly2)
|
||||||
|
{
|
||||||
|
// La polilinea deve contenere almeno due punti
|
||||||
|
if ( plPoly.GetPointNbr() < 2)
|
||||||
|
return false ;
|
||||||
|
// Riferimento alla lista dei punti
|
||||||
|
const PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
||||||
|
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||||
|
double dMinSqDist = SQ_INFINITO ;
|
||||||
|
auto itMinDistEnd = LoopList.end() ;
|
||||||
|
auto itStart = LoopList.begin() ;
|
||||||
|
auto itEnd = next( itStart) ;
|
||||||
|
for ( ; itEnd != LoopList.end() ; ++ itStart, ++ itEnd) {
|
||||||
|
// Distanza del punto dal segmento corrente
|
||||||
|
DistPointLine dDistCalc( ptP, itStart->first, itEnd->first) ;
|
||||||
|
double dSqDist ;
|
||||||
|
if ( dDistCalc.GetSqDist( dSqDist) && dSqDist < dMinSqDist) {
|
||||||
|
dMinSqDist = dSqDist ;
|
||||||
|
itMinDistEnd = itEnd ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Se il punto non sta sulla polilinea, non ha senso spezzare
|
||||||
|
if ( dMinSqDist > dToler * dToler)
|
||||||
|
return false ;
|
||||||
|
// Copio i punti opportuni nella prima parte
|
||||||
|
PNTULIST& LoopList1 = plPoly1.GetUPointList() ;
|
||||||
|
for ( auto it = LoopList.begin() ; it != itMinDistEnd ; ++ it)
|
||||||
|
LoopList1.emplace_back( it->first, it->second) ;
|
||||||
|
plPoly1.AddUPoint( 0, ptP) ;
|
||||||
|
// Copio i punti opportuni nella seconda parte
|
||||||
|
PNTULIST& LoopList2 = plPoly2.GetUPointList() ;
|
||||||
|
for ( auto it = itMinDistEnd ; it != LoopList.end() ; ++ it)
|
||||||
|
LoopList2.emplace_back( it->first, it->second) ;
|
||||||
|
plPoly2.AddUPoint( 0, ptP, false) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|||||||
+8
-8
@@ -165,7 +165,7 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
|
|||||||
for ( auto i : m_vExtInd) {
|
for ( auto i : m_vExtInd) {
|
||||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
||||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||||
! ccInt.GetCurveClassification( 0, ccClass) ||
|
! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) ||
|
||||||
ccClass.empty() || ccClass[0].nClass != CRVC_OUT) {
|
ccClass.empty() || ccClass[0].nClass != CRVC_OUT) {
|
||||||
bOk = false ;
|
bOk = false ;
|
||||||
break ;
|
break ;
|
||||||
@@ -178,7 +178,7 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
|
|||||||
continue ;
|
continue ;
|
||||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
||||||
if ( ccInt.GetCrossOrOverlapIntersCount() == 0 &&
|
if ( ccInt.GetCrossOrOverlapIntersCount() == 0 &&
|
||||||
ccInt.GetCurveClassification( 0, ccClass) &&
|
ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) &&
|
||||||
! ccClass.empty() && ccClass[0].nClass == CRVC_OUT) {
|
! ccClass.empty() && ccClass[0].nClass == CRVC_OUT) {
|
||||||
bOk = true ;
|
bOk = true ;
|
||||||
break ;
|
break ;
|
||||||
@@ -298,7 +298,7 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
|
|||||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[m_vExtInd[i]]) ;
|
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[m_vExtInd[i]]) ;
|
||||||
CRVCVECTOR ccClass ;
|
CRVCVECTOR ccClass ;
|
||||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||||
! ccInt.GetCurveClassification( 0, ccClass) ||
|
! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) ||
|
||||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||||
continue ;
|
continue ;
|
||||||
// verifica rispetto ai loop interni
|
// verifica rispetto ai loop interni
|
||||||
@@ -309,7 +309,7 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
|
|||||||
IntersCurveCurve ccInt2( *pMyCrv, *m_vpLoop[k]) ;
|
IntersCurveCurve ccInt2( *pMyCrv, *m_vpLoop[k]) ;
|
||||||
CRVCVECTOR ccClass2 ;
|
CRVCVECTOR ccClass2 ;
|
||||||
if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 ||
|
if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 ||
|
||||||
! ccInt2.GetCurveClassification( 0, ccClass2) ||
|
! ccInt2.GetCurveClassification( 0, EPS_SMALL, ccClass2) ||
|
||||||
ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) {
|
ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) {
|
||||||
bOk = false ;
|
bOk = false ;
|
||||||
break ;
|
break ;
|
||||||
@@ -1150,7 +1150,7 @@ SurfFlatRegion::CloneChunk( int nChunk) const
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const
|
SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const
|
||||||
{
|
{
|
||||||
// la curva deve già essere nel riferimento intrinseco della regione
|
// la curva deve già essere nel riferimento intrinseco della regione
|
||||||
// verifico lo stato
|
// verifico lo stato
|
||||||
@@ -1179,7 +1179,7 @@ SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass
|
|||||||
IntersCurveCurve ccInt( Crv, *pLoop) ;
|
IntersCurveCurve ccInt( Crv, *pLoop) ;
|
||||||
// classificazione
|
// classificazione
|
||||||
CRVCVECTOR ccPart ;
|
CRVCVECTOR ccPart ;
|
||||||
if ( ! ccInt.GetCurveClassification( 0, ccPart))
|
if ( ! ccInt.GetCurveClassification( 0, dLenMin, ccPart))
|
||||||
return false ;
|
return false ;
|
||||||
for ( auto& ccOne : ccPart) {
|
for ( auto& ccOne : ccPart) {
|
||||||
switch ( ccOne.nClass) {
|
switch ( ccOne.nClass) {
|
||||||
@@ -1272,7 +1272,7 @@ SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const
|
SurfFlatRegion::GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const
|
||||||
{
|
{
|
||||||
// verifico lo stato
|
// verifico lo stato
|
||||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||||
@@ -1293,7 +1293,7 @@ SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass)
|
|||||||
pCrvLoc = pCopyCrv ;
|
pCrvLoc = pCopyCrv ;
|
||||||
}
|
}
|
||||||
// esecuzione classificazione nel riferimento intrinseco
|
// esecuzione classificazione nel riferimento intrinseco
|
||||||
return MyGetCurveClassification( *pCrvLoc, ccClass) ;
|
return MyGetCurveClassification( *pCrvLoc, dLenMin, ccClass) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
+2
-2
@@ -92,7 +92,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
|||||||
const SurfTriMesh* GetAuxSurf( void) const override ;
|
const SurfTriMesh* GetAuxSurf( void) const override ;
|
||||||
SurfFlatRegion* CloneChunk( int nChunk) const override ;
|
SurfFlatRegion* CloneChunk( int nChunk) const override ;
|
||||||
bool GetChunkCentroid( int nChunk, Point3d& ptCen) const override ;
|
bool GetChunkCentroid( int nChunk, Point3d& ptCen) const override ;
|
||||||
bool GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const override ;
|
bool GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const override ;
|
||||||
int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides
|
int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides
|
||||||
|
|
||||||
public : // IGeoObjRW
|
public : // IGeoObjRW
|
||||||
@@ -131,7 +131,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
|||||||
ICurve* GetMyLoop( int nChunk, int nLoop) const ; // nChunk 0-based, nLoop 0-based (1°esterno, successivi interni)
|
ICurve* GetMyLoop( int nChunk, int nLoop) const ; // nChunk 0-based, nLoop 0-based (1°esterno, successivi interni)
|
||||||
void ResetAuxSurf( void) const ;
|
void ResetAuxSurf( void) const ;
|
||||||
bool ConvertArcsToBezierCurves( void) ;
|
bool ConvertArcsToBezierCurves( void) ;
|
||||||
bool MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const ;
|
bool MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const ;
|
||||||
static bool MySelectCurves( const PCRV_DEQUE& vpLoop, const SurfFlatRegion& Other,
|
static bool MySelectCurves( const PCRV_DEQUE& vpLoop, const SurfFlatRegion& Other,
|
||||||
int nType1, bool bInvert1, int nType2, bool bInvert2, PCRV_DEQUE& vpCurve) ;
|
int nType1, bool bInvert1, int nType2, bool bInvert2, PCRV_DEQUE& vpCurve) ;
|
||||||
static bool MyChainCurves( PCRV_DEQUE& vpCurve, PCRV_DEQUE& vpLoop) ;
|
static bool MyChainCurves( PCRV_DEQUE& vpCurve, PCRV_DEQUE& vpLoop) ;
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ SurfFlatRegion::MySelectCurves( const PCRV_DEQUE& vpLoop, const SurfFlatRegion&
|
|||||||
for ( auto& pLoop : vpLoop) {
|
for ( auto& pLoop : vpLoop) {
|
||||||
// eseguo classificazione
|
// eseguo classificazione
|
||||||
CRVCVECTOR ccClass ;
|
CRVCVECTOR ccClass ;
|
||||||
if ( ! Other.MyGetCurveClassification( *pLoop, ccClass))
|
if ( ! Other.MyGetCurveClassification( *pLoop, EPS_SMALL, ccClass))
|
||||||
return false ;
|
return false ;
|
||||||
// creo intervalli validi, tenendo classificazioni ricevute
|
// creo intervalli validi, tenendo classificazioni ricevute
|
||||||
Intervals inOk1( EPS_PARAM), inOk2( EPS_PARAM) ;
|
Intervals inOk1( EPS_PARAM), inOk2( EPS_PARAM) ;
|
||||||
@@ -441,7 +441,7 @@ SurfFlatRegion::MyNewSurfFromLoops( PCRV_DEQUE& vpLoop)
|
|||||||
CRVCVECTOR ccClass ;
|
CRVCVECTOR ccClass ;
|
||||||
IntersCurveCurve ccInt( *vpLoop[l], *pExtLoop) ;
|
IntersCurveCurve ccInt( *vpLoop[l], *pExtLoop) ;
|
||||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||||
! ccInt.GetCurveClassification( 0, ccClass) ||
|
! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) ||
|
||||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||||
continue ;
|
continue ;
|
||||||
// lo inserisco
|
// lo inserisco
|
||||||
|
|||||||
+74
-37
@@ -3401,10 +3401,8 @@ SurfTriMesh::Invert( void)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
SurfTriMesh::CutByTriangles( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif)
|
||||||
{
|
{
|
||||||
#define UseTria 1
|
|
||||||
#if UseTria
|
|
||||||
// la superficie deve essere validata
|
// la superficie deve essere validata
|
||||||
if ( m_nStatus != OK)
|
if ( m_nStatus != OK)
|
||||||
return false ;
|
return false ;
|
||||||
@@ -3430,7 +3428,6 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
|||||||
++ m_nTimeStamp ;
|
++ m_nTimeStamp ;
|
||||||
|
|
||||||
// sistemo i triangoli (eventualmente li elimino)
|
// sistemo i triangoli (eventualmente li elimino)
|
||||||
bool bModif = false ;
|
|
||||||
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
|
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
|
||||||
// salto i triangoli cancellati e quelli aggiunti
|
// salto i triangoli cancellati e quelli aggiunti
|
||||||
if ( m_vTria[i].nIdVert[0] == SVT_DEL || m_vTria[i].nTemp == m_nTimeStamp)
|
if ( m_vTria[i].nIdVert[0] == SVT_DEL || m_vTria[i].nTemp == m_nTimeStamp)
|
||||||
@@ -3609,41 +3606,38 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// se effettuate modifiche
|
|
||||||
if ( bModif) {
|
|
||||||
// aggiorno tutto
|
|
||||||
if ( ! AdjustVertices() || ! DoCompacting())
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
bool bModif = false ;
|
SurfTriMesh::CutByFacets( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif)
|
||||||
|
{
|
||||||
// Setto i triangoli come né fuori né dentro.
|
// Setto posizione triangoli non definita
|
||||||
int nTriaNum = GetTriangleSize() ;
|
for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT)
|
||||||
for ( int nT = 0 ; nT < nTriaNum ; ++ nT) {
|
|
||||||
m_vTria[nT].nTempPart = 0 ;
|
m_vTria[nT].nTempPart = 0 ;
|
||||||
}
|
|
||||||
|
|
||||||
INTERSCHAINMAP IntersLineMap ;
|
INTERSCHAINMAP IntersLineMap ;
|
||||||
|
|
||||||
// Ciclo su tutte le facce.
|
// Ciclo su tutte le facce.
|
||||||
int nFacetNum = GetFacetCount() ;
|
for ( int nF = 0 ; nF < GetFacetCount() ; ++ nF) {
|
||||||
for ( int nF = 0 ; nF < nFacetNum ; ++ nF) {
|
|
||||||
// Dati della faccia
|
// Dati della faccia
|
||||||
POLYLINEVECTOR vLoopVec ;
|
POLYLINEVECTOR vLoopVec ;
|
||||||
GetFacetLoops( nF, vLoopVec) ;
|
GetFacetLoops( nF, vLoopVec) ;
|
||||||
if ( vLoopVec.empty())
|
if ( vLoopVec.empty())
|
||||||
continue ;
|
continue ;
|
||||||
PtrOwner<SurfFlatRegion> pReg( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( vLoopVec))) ;
|
// Verifico la posizione del loop esterno
|
||||||
if ( IsNull( pReg))
|
int nIntType = VerifyLoopPlane( vLoopVec[0], plPlane) ;
|
||||||
return false ;
|
// Se interseca il piano di taglio, calcolo la divisione della faccia
|
||||||
LineFacetClassVector IntersLinePart ;
|
LineFacetClassVector IntersLinePart ;
|
||||||
int nIntType = IntersFacetPlane( *pReg, vLoopVec[0], plPlane, IntersLinePart) ;
|
if ( nIntType == FPI_CUT) {
|
||||||
if ( nIntType == FacetPlaneIntersType::FPI_CUT) {
|
PtrOwner<SurfFlatRegion> pReg( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( vLoopVec))) ;
|
||||||
|
if ( IsNull( pReg) || ! pReg->IsValid())
|
||||||
|
return false ;
|
||||||
|
nIntType = IntersFacetPlane( *pReg, plPlane, IntersLinePart) ;
|
||||||
|
}
|
||||||
|
// Gestione dei risultati
|
||||||
|
if ( nIntType == FPI_CUT) {
|
||||||
for ( int nPart = 0 ; nPart < int( IntersLinePart.size()) ; ++ nPart) {
|
for ( int nPart = 0 ; nPart < int( IntersLinePart.size()) ; ++ nPart) {
|
||||||
// Salvo intersezione per la faccia.
|
// Salvo intersezione per la faccia.
|
||||||
auto it = IntersLineMap.find( nF) ;
|
auto it = IntersLineMap.find( nF) ;
|
||||||
@@ -3655,26 +3649,28 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( nIntType == FacetPlaneIntersType::FPI_ON) {
|
else if ( nIntType == FPI_ON) {
|
||||||
INTVECTOR vT ;
|
INTVECTOR vT ;
|
||||||
GetAllTriaInFacet( nF, vT) ;
|
GetAllTriaInFacet( nF, vT) ;
|
||||||
|
Vector3d vtNf ;
|
||||||
|
GetFacetNormal( nF, vtNf) ;
|
||||||
for ( auto& nT : vT)
|
for ( auto& nT : vT)
|
||||||
m_vTria[nT].nTempPart = pReg->GetNormVersor() * plPlane.GetVersN() > 0. ? 2 : - 2 ;
|
m_vTria[nT].nTempPart = ( vtNf * plPlane.GetVersN() > 0 ? 2 : -2) ;
|
||||||
}
|
}
|
||||||
else if ( nIntType == FacetPlaneIntersType::FPI_INN) {
|
else if ( nIntType == FPI_IN) {
|
||||||
INTVECTOR vT ;
|
INTVECTOR vT ;
|
||||||
GetAllTriaInFacet( nF, vT) ;
|
GetAllTriaInFacet( nF, vT) ;
|
||||||
for ( auto& nT : vT)
|
for ( auto& nT : vT)
|
||||||
m_vTria[nT].nTempPart = 1 ;
|
m_vTria[nT].nTempPart = 1 ;
|
||||||
}
|
}
|
||||||
else if ( nIntType == FacetPlaneIntersType::FPI_OUT) {
|
else if ( nIntType == FPI_OUT) {
|
||||||
INTVECTOR vT ;
|
INTVECTOR vT ;
|
||||||
GetAllTriaInFacet( nF, vT) ;
|
GetAllTriaInFacet( nF, vT) ;
|
||||||
for ( auto& nT : vT)
|
for ( auto& nT : vT)
|
||||||
m_vTria[nT].nTempPart = - 1 ;
|
m_vTria[nT].nTempPart = -1 ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Divido le facce.
|
// Divido le facce.
|
||||||
@@ -3683,13 +3679,54 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
|||||||
INTERSEDGEMAP EdgeInterLineMap, EdgeEdgeLineMap ;
|
INTERSEDGEMAP EdgeInterLineMap, EdgeEdgeLineMap ;
|
||||||
RetriangulateFacetPieces( NewFacet, EdgeInterLineMap, EdgeEdgeLineMap) ;
|
RetriangulateFacetPieces( NewFacet, EdgeInterLineMap, EdgeEdgeLineMap) ;
|
||||||
|
|
||||||
int nNumTria = GetTriangleSize() ;
|
// Elimino i triangoli superflui
|
||||||
for ( int nT = 0 ; nT < nNumTria ; ++ nT)
|
for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT) {
|
||||||
if ( m_vTria[nT].nTempPart == - 1 || m_vTria[nT].nTempPart == - 2 || ( ! bSaveOnEq && m_vTria[nT].nTempPart == 2))
|
if ( m_vTria[nT].nTempPart == 0 ||
|
||||||
|
m_vTria[nT].nTempPart == -1 ||
|
||||||
|
m_vTria[nT].nTempPart == -2 ||
|
||||||
|
( ! bSaveOnEq && m_vTria[nT].nTempPart == 2)) {
|
||||||
RemoveTriangle( nT) ;
|
RemoveTriangle( nT) ;
|
||||||
|
bModif = true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return AdjustVertices() && DoCompacting() ;
|
return true ;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
||||||
|
{
|
||||||
|
// la superficie deve essere validata
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// recupero il numero originale di triangoli e di facce
|
||||||
|
int nTriaOriCnt = GetTriangleCount() ;
|
||||||
|
int nFacetOriCnt = GetFacetCount() ;
|
||||||
|
|
||||||
|
// eseguo il taglio con il metodo delle faccette o dei triangoli (per ora solo coi triangoli)
|
||||||
|
bool bModif = false ;
|
||||||
|
if ( true || ! CutByFacets( plPlane, bSaveOnEq, bModif)) {
|
||||||
|
bModif = false ;
|
||||||
|
if ( ! CutByTriangles( plPlane, bSaveOnEq, bModif))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// se effettuate modifiche
|
||||||
|
if ( bModif) {
|
||||||
|
// aggiorno tutto
|
||||||
|
if ( ! AdjustVertices() || ! DoCompacting())
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// se superficie originale a facce, cerco di semplificarle in ogni caso
|
||||||
|
if ( nFacetOriCnt < 200 || double( nTriaOriCnt) / nFacetOriCnt > 4) {
|
||||||
|
if ( ! SimplifyFacets( 500.0))
|
||||||
|
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Cut")
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
+8
-4
@@ -121,7 +121,7 @@ struct LineFacetClass {
|
|||||||
nTypeA = 0 ;
|
nTypeA = 0 ;
|
||||||
nTypeB = 0 ;
|
nTypeB = 0 ;
|
||||||
}
|
}
|
||||||
LineFacetClass( const Point3d& ptS, const Point3d ptE, int nTpA, int nTpB) {
|
LineFacetClass( const Point3d& ptS, const Point3d& ptE, int nTpA, int nTpB) {
|
||||||
ptSt = ptS ;
|
ptSt = ptS ;
|
||||||
ptEn = ptE ;
|
ptEn = ptE ;
|
||||||
nTypeA = nTpA ;
|
nTypeA = nTpA ;
|
||||||
@@ -131,7 +131,7 @@ struct LineFacetClass {
|
|||||||
typedef std::vector<LineFacetClass> LineFacetClassVector ;
|
typedef std::vector<LineFacetClass> LineFacetClassVector ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
enum FacetPlaneIntersType { FPI_ERROR = 0, FPI_CUT = 1, FPI_INN = 2, FPI_OUT = 3, FPI_ON = 4 } ;
|
enum FacetPlaneIntersType { FPI_ERROR = 0, FPI_CUT = 1, FPI_IN = 2, FPI_OUT = 3, FPI_ON = 4 } ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Definizione strutture e contenitori
|
// Definizione strutture e contenitori
|
||||||
@@ -381,19 +381,23 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
void ResetHashGrids3d( void) const ;
|
void ResetHashGrids3d( void) const ;
|
||||||
bool VerifyHashGrids3d( void) const ;
|
bool VerifyHashGrids3d( void) const ;
|
||||||
bool VerifyConnection( void) const ;
|
bool VerifyConnection( void) const ;
|
||||||
|
bool CutByTriangles( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ;
|
||||||
|
bool CutByFacets( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ;
|
||||||
bool DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMATRIX& cvBoundClosedLoopVec, BOOLVECTOR& vbInOut) ;
|
bool DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMATRIX& cvBoundClosedLoopVec, BOOLVECTOR& vbInOut) ;
|
||||||
bool RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf, bool& bModif) ;
|
bool RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf, bool& bModif) ;
|
||||||
bool AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf) ;
|
bool AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf) ;
|
||||||
bool IntersectTriMeshTriangle( SurfTriMesh& Other) ;
|
bool IntersectTriMeshTriangle( SurfTriMesh& Other) ;
|
||||||
int IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& ExtLoop, const Plane3d& plCutPlane,
|
int VerifyLoopPlane( const PolyLine& ExtLoop, const Plane3d& plCutPlane) ;
|
||||||
|
int IntersFacetPlane( const SurfFlatRegion& Region, const Plane3d& plCutPlane,
|
||||||
LineFacetClassVector& IntersLinePart) ;
|
LineFacetClassVector& IntersLinePart) ;
|
||||||
bool IntersFacetFacet( const SurfFlatRegion& RegionA, const PolyLine& ExtLoopA,
|
bool IntersFacetFacet( const SurfFlatRegion& RegionA, const PolyLine& ExtLoopA,
|
||||||
const SurfFlatRegion& RegionB, const PolyLine& ExtLoopB,
|
const SurfFlatRegion& RegionB, const PolyLine& ExtLoopB,
|
||||||
LineFacetClassVector& IntersLinePart) ;
|
LineFacetClassVector& IntersLinePart) ;
|
||||||
bool ItersectTriMeshFacets( SurfTriMesh& Other) ;
|
bool IntersectTriMeshFacets( SurfTriMesh& Other) ;
|
||||||
bool RetriangulateFacetPieces( const PieceMap& NewFacet,
|
bool RetriangulateFacetPieces( const PieceMap& NewFacet,
|
||||||
const INTERSEDGEMAP& EdgeInterLineMap,
|
const INTERSEDGEMAP& EdgeInterLineMap,
|
||||||
const INTERSEDGEMAP& EdgeEdgeLineMap) ;
|
const INTERSEDGEMAP& EdgeEdgeLineMap) ;
|
||||||
|
bool SimplifyFacets( double dMaxEdgeLen) ;
|
||||||
bool EdgeInteriorContactManager( const SurfTriMesh& OthSurf,
|
bool EdgeInteriorContactManager( const SurfTriMesh& OthSurf,
|
||||||
const INTERSCHAINMAP& InterInterLineMap,
|
const INTERSCHAINMAP& InterInterLineMap,
|
||||||
const INTERSEDGEMAP& EdgeInterLineMap) ;
|
const INTERSEDGEMAP& EdgeInterLineMap) ;
|
||||||
|
|||||||
+382
-785
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,250 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2021-2021
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : SurfTriMeshUtilities.cpp Data : 01.11.21 Versione : 2.3k1
|
||||||
|
// Contenuto : Implementazione funzioni di utilità di Superfici TriMesh.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 25.10.21 LM Creazione modulo.
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//--------------------------- Include ----------------------------------------
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "Triangulate.h"
|
||||||
|
#include "SurfTriMesh.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static bool
|
||||||
|
IsVertex( PNTULIST& PointList, PNTULIST::const_iterator itCurr)
|
||||||
|
{
|
||||||
|
// recupero il punto precedente
|
||||||
|
PNTULIST::const_iterator itPrev ;
|
||||||
|
if ( itCurr == PointList.begin())
|
||||||
|
itPrev = prev( PointList.end(), 2) ;
|
||||||
|
else
|
||||||
|
itPrev = prev( itCurr) ;
|
||||||
|
// recupero il punto successivo
|
||||||
|
auto itNext = next( itCurr) ;
|
||||||
|
if ( itNext == PointList.end())
|
||||||
|
itNext = next( PointList.begin()) ;
|
||||||
|
// se cambia faccia adiacente tra prima e dopo, va bene
|
||||||
|
if ( itPrev->second != itCurr->second)
|
||||||
|
return true ;
|
||||||
|
// se lati aperti e cambia direzione tra prima e dopo, va bene
|
||||||
|
if ( itPrev->second == -1) {
|
||||||
|
DistPointLine PointLineDistCalc( itCurr->first, itPrev->first, itNext->first) ;
|
||||||
|
double dDist ;
|
||||||
|
if ( PointLineDistCalc.GetDist( dDist) && dDist > EPS_SMALL)
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// altrimenti non va bene
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static bool
|
||||||
|
ChooseGoodStartPoint( PNTULIST& PointList)
|
||||||
|
{
|
||||||
|
// se il punto iniziale è un vertice, non devo fare alcunché
|
||||||
|
if ( IsVertex( PointList, PointList.begin()))
|
||||||
|
return true ;
|
||||||
|
// altrimenti cerco il vertice più vicino
|
||||||
|
for ( auto it = next( PointList.begin()) ; it != PointList.end() ; ++it) {
|
||||||
|
if ( IsVertex( PointList, it)) {
|
||||||
|
// cancello ultimo punto ( coincide con primo)
|
||||||
|
PointList.pop_back() ;
|
||||||
|
// sposto la parte iniziale dei punti alla fine
|
||||||
|
PointList.splice( PointList.end(), PointList, PointList.begin(), it) ;
|
||||||
|
// aggiungo punto finale come copia dell'iniziale
|
||||||
|
PointList.push_back( PointList.front()) ;
|
||||||
|
// ho finito
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static bool
|
||||||
|
AdjustLoop( PNTULIST& PointList, double dMaxEdgeLen, bool& bModif)
|
||||||
|
{
|
||||||
|
// Ciclo sui punti del loop
|
||||||
|
auto itLast = PointList.begin() ;
|
||||||
|
for ( auto it = next( itLast) ; it != PointList.end() ; ++ it) {
|
||||||
|
|
||||||
|
// Se dal punto corrente inizia un segmento adiacente a un'altra faccia
|
||||||
|
if ( itLast->second != it->second) {
|
||||||
|
// Elimino i punti interni
|
||||||
|
auto itNextToLast = next( itLast) ;
|
||||||
|
for ( auto itInn = itNextToLast ; itInn != it ; ) {
|
||||||
|
itInn = PointList.erase( itInn) ;
|
||||||
|
bModif = true ;
|
||||||
|
}
|
||||||
|
// Se la lunghezza del segmento supera il limite imposto
|
||||||
|
double dSegLen = Dist( it->first, itLast->first) ;
|
||||||
|
if ( dSegLen > dMaxEdgeLen) {
|
||||||
|
// determino il numero di step
|
||||||
|
double dRatio = dSegLen / dMaxEdgeLen ;
|
||||||
|
int nStepCount = int( dRatio) + 1 ;
|
||||||
|
// inserisco i punti
|
||||||
|
auto itAdd = it ;
|
||||||
|
for ( int nP = 1 ; nP < nStepCount ; ++ nP) {
|
||||||
|
double dCoeff = double( nP) / nStepCount ;
|
||||||
|
itAdd = PointList.insert( itAdd, POINTU( Media( itLast->first, it->first, 1 - dCoeff), itLast->second)) ;
|
||||||
|
bModif = true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Nuovo punto di riferimento
|
||||||
|
itLast = it ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se sono due segmenti liberi non allineati
|
||||||
|
else if ( itLast->second == - 1) {
|
||||||
|
// Calcolo se i punti compresi fra gli estremi sono allineati
|
||||||
|
bool bAreAligned = true ;
|
||||||
|
auto itNextToLast = next( itLast) ;
|
||||||
|
for ( auto itInn = itNextToLast ; itInn != it && bAreAligned ; ++ itInn) {
|
||||||
|
DistPointLine PointLineDistCalc( itInn->first, itLast->first, it->first) ;
|
||||||
|
double dDist ;
|
||||||
|
if ( PointLineDistCalc.GetDist( dDist))
|
||||||
|
bAreAligned = ( dDist < EPS_SMALL) ;
|
||||||
|
}
|
||||||
|
// Se i punti sono allineati
|
||||||
|
if ( bAreAligned) {
|
||||||
|
// Verifico se il successivo punto non è più allineato
|
||||||
|
auto itNextToCurr = next( it) ;
|
||||||
|
if ( itNextToCurr != PointList.end()) {
|
||||||
|
for ( auto itInn = itNextToLast ; itInn != itNextToCurr && bAreAligned ; ++ itInn) {
|
||||||
|
DistPointLine PointLineDistCalc( itInn->first, itLast->first, itNextToCurr->first) ;
|
||||||
|
double dDist ;
|
||||||
|
if ( PointLineDistCalc.GetDist( dDist))
|
||||||
|
bAreAligned = ( dDist < EPS_SMALL) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Se ho trovato un insieme massimale di punti allineati li processo
|
||||||
|
if ( ! bAreAligned || itNextToCurr == PointList.end()) {
|
||||||
|
// Elimino i punti interni
|
||||||
|
for ( auto itInn = itNextToLast ; itInn != it ; ) {
|
||||||
|
itInn = PointList.erase( itInn) ;
|
||||||
|
bModif = true ;
|
||||||
|
}
|
||||||
|
// Se la lunghezza del segmento supera il limite imposto
|
||||||
|
double dSegLen = Dist( it->first, itLast->first) ;
|
||||||
|
if ( dSegLen > dMaxEdgeLen) {
|
||||||
|
// determino il numero di step
|
||||||
|
double dRatio = dSegLen / dMaxEdgeLen ;
|
||||||
|
int nStepCount = int( dRatio) + 1 ;
|
||||||
|
// inserisco i punti
|
||||||
|
auto itAdd = it ;
|
||||||
|
for ( int nP = 1 ; nP < nStepCount ; ++ nP) {
|
||||||
|
double dCoeff = double( nP) / nStepCount ;
|
||||||
|
itAdd = PointList.insert( itAdd, POINTU( Media( itLast->first, it->first, 1 - dCoeff), itLast->second)) ;
|
||||||
|
bModif = true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Nuovo punto di riferimento
|
||||||
|
itLast = it ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfTriMesh::SimplifyFacets( double dMaxEdgeLen)
|
||||||
|
{
|
||||||
|
// La trimesh deve essere valida
|
||||||
|
if ( ! IsValid())
|
||||||
|
return false ;
|
||||||
|
// Se la lunghezza massima del lato del triangolo sul bordo della faccia è nulla, non devo fare alcunché
|
||||||
|
if ( dMaxEdgeLen < EPS_SMALL)
|
||||||
|
return true ;
|
||||||
|
|
||||||
|
// Recupero il numero delle facce (esegue anche una verifica delle stesse)
|
||||||
|
int nFacetCnt = GetFacetCount() ;
|
||||||
|
|
||||||
|
// Ciclo sulle facce della mesh per trovare quelle da ritriangolare
|
||||||
|
unordered_map< int, pair< PNTVECTOR, INTVECTOR>> FacetMap ;
|
||||||
|
for ( int nF = 0 ; nF < nFacetCnt ; ++ nF) {
|
||||||
|
|
||||||
|
// Recupero i loop della faccia (il parametro indica la faccia adiacente)
|
||||||
|
POLYLINEVECTOR LoopVec ;
|
||||||
|
GetFacetLoops( nF, LoopVec) ;
|
||||||
|
|
||||||
|
// Ciclo sui loop della faccia
|
||||||
|
bool bToRetriangulate = false ;
|
||||||
|
for ( int nL = 0 ; nL < int( LoopVec.size()) ; ++ nL) {
|
||||||
|
|
||||||
|
// Lista dei punti del loop
|
||||||
|
PNTULIST& PointList = LoopVec[nL].GetUPointList() ;
|
||||||
|
|
||||||
|
// Mi assicuro che il punto iniziale/finale non sia all'interno di un possibile segmento
|
||||||
|
if ( ! ChooseGoodStartPoint( PointList))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// Sistemo il loop
|
||||||
|
bool bModif = false ;
|
||||||
|
if ( ! AdjustLoop( PointList, dMaxEdgeLen, bModif))
|
||||||
|
return false ;
|
||||||
|
if ( bModif)
|
||||||
|
bToRetriangulate = true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se da ritriangolare,
|
||||||
|
if ( bToRetriangulate) {
|
||||||
|
// Eseguo la ritriangolazione della faccia
|
||||||
|
PNTVECTOR vPt ;
|
||||||
|
INTVECTOR vTr ;
|
||||||
|
if ( Triangulate().Make( LoopVec, vPt, vTr)) {
|
||||||
|
FacetMap.emplace( nF, make_pair( vPt, vTr)) ;
|
||||||
|
}
|
||||||
|
// Se non riesco a triangolare anche solo questa faccia, interrompo tutto
|
||||||
|
else
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ciclo sulle facce da ritriangolare per eliminare i triangoli (nel contempo salvo flag colore)
|
||||||
|
unordered_map< int, int> ColorMap ;
|
||||||
|
for ( auto itF = FacetMap.begin() ; itF != FacetMap.end() ; ++ itF) {
|
||||||
|
// Recupero i triangoli della faccia
|
||||||
|
INTVECTOR vFacetTria ;
|
||||||
|
GetAllTriaInFacet( itF->first, vFacetTria) ;
|
||||||
|
// Salvo il colore della faccia da flag di un suo triangolo
|
||||||
|
ColorMap.emplace( itF->first, m_vTria[m_vFacet[itF->first]].nTFlag) ;
|
||||||
|
// Cancello i triangoli della faccia.
|
||||||
|
for ( int nT : vFacetTria)
|
||||||
|
RemoveTriangle( nT) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applico le nuove triangolazioni delle facce
|
||||||
|
for ( auto itFac = FacetMap.begin() ; itFac != FacetMap.end() ; ++ itFac) {
|
||||||
|
const PNTVECTOR& vPt = itFac->second.first ;
|
||||||
|
const INTVECTOR& vTr = itFac->second.second ;
|
||||||
|
// Inserisco i nuovi triangoli
|
||||||
|
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||||
|
int nNewId[3] = { AddVertex( vPt[vTr[n]]),
|
||||||
|
AddVertex( vPt[vTr[n + 1]]),
|
||||||
|
AddVertex( vPt[vTr[n + 2]])} ;
|
||||||
|
auto itCol = ColorMap.find( itFac->first) ;
|
||||||
|
int nTFlag = ( itCol != ColorMap.end() ? itCol->second : 0) ;
|
||||||
|
int nNewTriaId = AddTriangle( nNewId, nTFlag) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dichiaro necessità ricalcolo della grafica e di hashgrids3d
|
||||||
|
m_OGrMgr.Reset() ;
|
||||||
|
ResetHashGrids3d() ;
|
||||||
|
|
||||||
|
// Eseguo aggiustamenti
|
||||||
|
return ( AdjustVertices() && DoCompacting()) ;
|
||||||
|
}
|
||||||
+2
-2
@@ -220,7 +220,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
|
|||||||
|
|
||||||
// Determino le intersezioni della retta con la regione
|
// Determino le intersezioni della retta con la regione
|
||||||
CRVCVECTOR IntersectionResults ;
|
CRVCVECTOR IntersectionResults ;
|
||||||
Surf.GetCurveClassification( GridLine, IntersectionResults) ;
|
Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ;
|
||||||
|
|
||||||
// Analizzo le parti in cui la retta è stata divisa
|
// Analizzo le parti in cui la retta è stata divisa
|
||||||
int nPart = int( IntersectionResults.size()) ;
|
int nPart = int( IntersectionResults.size()) ;
|
||||||
@@ -327,7 +327,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
|
|||||||
|
|
||||||
// Determino le intersezioni della retta con la regione
|
// Determino le intersezioni della retta con la regione
|
||||||
CRVCVECTOR IntersectionResults ;
|
CRVCVECTOR IntersectionResults ;
|
||||||
Surf.GetCurveClassification( GridLine, IntersectionResults) ;
|
Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ;
|
||||||
|
|
||||||
// Analizzo le parti
|
// Analizzo le parti
|
||||||
int nPart = int( IntersectionResults.size()) ;
|
int nPart = int( IntersectionResults.size()) ;
|
||||||
|
|||||||
Reference in New Issue
Block a user