Compare commits

...

13 Commits

Author SHA1 Message Date
LorenzoM d1cf3f1f2f Tolto un commento 2021-11-05 17:06:12 +01:00
LorenzoM ffa7c3dad5 Corretto errore bModif 2021-11-05 17:00:47 +01:00
LorenzoM a3502b5c07 Merge remote-tracking branch 'origin/master' into develop 2021-11-04 12:40:10 +01:00
LorenzoM a9259e8679 Merge modifiche Dario su SurfTriMeshBoolean 2021-11-04 12:37:25 +01:00
LorenzoM d3bc7bee64 TEST Taglio generalizzato 2021-11-04 12:30:24 +01:00
DarioS aa82c82ddc EgtGeomKernel 2.3k2 :
- corretta SurfTriMesh::SimplifyFacets.
2021-11-04 10:03:35 +01:00
DarioS 8a6dbf044e EgtGeomKernel :
- piccole modifiche in Cut e GeneralizedCut per eseguire il più possibile SimplfyFacet.
2021-11-03 13:30:26 +01:00
DarioS 76d009ddbe EgtGeomKernel 2.3k1 :
- corretto offset di segmenti di retta singoli con estrusione
- modifiche per calcolo taglio superfici TriMesh
- modifiche a funzione SimplifyFacets di superfici TriMesh.
2021-11-02 08:19:11 +01:00
LorenzoM 6deff01b6e Modifiche generalized cut 2021-10-29 17:17:51 +02:00
LorenzoM e79bb117d2 Pulizia codice simplify facet 2021-10-27 17:53:12 +02:00
LorenzoM 2ea4b59b9b Aggiunta funzione FimplifyFacets in TriMesh 2021-10-26 18:11:58 +02:00
DarioS 6e9465247f EgtGeomKernel 2.3j1 :
- diemnticato un file.
2021-10-24 18:00:00 +02:00
DarioS 1d1fb41212 EgtGeomKernel 2.3j :
- modifiche a SurfTriMesh::Cut (più semplice abilitare calcolo con facce invece di triangoli)
- ora CurveClassification (di Regioni e Curve) ricevono anche il parametro dMinLen.
2021-10-24 17:57:53 +02:00
18 changed files with 1112 additions and 990 deletions
+2 -2
View File
@@ -13,8 +13,8 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "\EgtDev\Include\EGkBBox3d.h"
#include "\EgtDev\Include\EGkFrame3d.h"
#include "/EgtDev/Include/EGkBBox3d.h"
#include "/EgtDev/Include/EGkFrame3d.h"
#include <algorithm>
using namespace std ;
+1 -1
View File
@@ -3134,7 +3134,7 @@ CurveComposite::RemoveUndercutOnY( double dLinTol, double dAngTolDeg)
pSfrCut->Translate( b3Box.GetMin() - Point3d( 10 * EPS_SMALL, dLen, 0)) ;
// calcolo la classificazione della curva rispetto alla regione
CRVCVECTOR ccClass ;
if ( ! pSfrCut->GetCurveClassification( *pOutLoop, ccClass))
if ( ! pSfrCut->GetCurveClassification( *pOutLoop, EPS_SMALL, ccClass))
return false ;
// determino gli intervalli di curva da conservare
Intervals inOk ;
+10 -11
View File
@@ -23,33 +23,30 @@
bool
CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, double dLinTol, MDCVECTOR& vApproxMin)
{
double dSqDist ;
double dPar ;
double dUIni ;
double dUFin ;
Point3d ptIni ;
Point3d ptFin ;
double dMinDist ;
double dSqMinDist ;
MinDistCalc approxMin ;
vApproxMin.reserve( 4) ;
vApproxMin.clear() ;
bool bFound = false ;
bool bOnEnd = false ;
vApproxMin.reserve( 4) ;
vApproxMin.clear() ;
double dUIni, dUFin ;
Point3d ptIni, ptFin ;
double dMinDist, dSqMinDist ;
for ( bool bLine = PL.GetFirstULine( &dUIni, &ptIni, &dUFin, &ptFin) ;
bLine ;
bLine = PL.GetNextULine( &dUIni, &ptIni, &dUFin, &ptFin)) {
// calcolo la distanza del punto dal segmento
DistPointLine dstPtLn( ptP, ptIni, ptFin) ;
double dSqDist ;
if ( ! dstPtLn.GetSqDist( dSqDist))
continue ;
// altro punto con la stessa minima distanza già trovata
if ( bFound && abs( dSqDist - dSqMinDist) < 2 * dMinDist * dLinTol) {
// salvo i dati nella struttura
MinDistCalc approxMin ;
approxMin.dDist = dMinDist ;
dstPtLn.GetMinDistPoint( approxMin.ptQ) ;
double dPar ;
dstPtLn.GetParamAtMinDistPoint( dPar) ;
approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ;
approxMin.dParMin = dUIni ;
@@ -66,8 +63,10 @@ CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, double dLinTol, MDCV
dSqMinDist = dSqDist ;
dMinDist = sqrt( dSqMinDist) ;
// salvo i dati nella struttura
MinDistCalc approxMin ;
approxMin.dDist = dMinDist ;
dstPtLn.GetMinDistPoint( approxMin.ptQ) ;
double dPar ;
dstPtLn.GetParamAtMinDistPoint( dPar) ;
approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ;
approxMin.dParMin = dUIni ;
BIN
View File
Binary file not shown.
+1
View File
@@ -392,6 +392,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="SurfFlatRegionBooleans.cpp" />
<ClCompile Include="SurfFlatRegionOffset.cpp" />
<ClCompile Include="SurfTriMeshBooleans.cpp" />
<ClCompile Include="SurfTriMeshUtilities.cpp" />
<ClCompile Include="TextureData.cpp" />
<ClCompile Include="Tool.cpp" />
<ClCompile Include="UserObjDefault.cpp" />
+3
View File
@@ -453,6 +453,9 @@
<ClCompile Include="CDeRectPrismoidTria.cpp">
<Filter>File di origine\GeoCollision</Filter>
</ClCompile>
<ClCompile Include="SurfTriMeshUtilities.cpp">
<Filter>File di origine\Geo</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
+1 -1
View File
@@ -7647,7 +7647,7 @@ GdbExecutor::CurveCopyBySplitClass( const STRVECTOR& vsParams)
IntersCurveCurve intCC( *pCrv, *pCloCrv, true) ;
// recupero la classificazione della prima curva
CRVCVECTOR ccClass ;
if ( ! intCC.GetCurveClassification( 0, ccClass))
if ( ! intCC.GetCurveClassification( 0, EPS_SMALL, ccClass))
return false ;
// recupero gli indici dei gruppi destinazione e i loro riferimenti
const int N_GRP = 4 ;
+10 -8
View File
@@ -391,7 +391,7 @@ IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d
//----------------------------------------------------------------------------
bool
IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
IntersCurveCurve::GetCurveClassification( int nCrv, double dLenMin, CRVCVECTOR& ccClass)
{
// pulisco vettore classificazioni
ccClass.clear() ;
@@ -407,7 +407,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
return false ;
// se esiste almeno una intersezione
if ( m_nIntersCount >= 1)
return CalcCurveClassification( m_pCurve[0], m_Info, ccClass) ;
return CalcCurveClassification( m_pCurve[0], m_Info, dLenMin, ccClass) ;
// altrimenti la curva è completamente interna oppure completamente esterna
else
return CalcCurveInOrOut( m_pCurve[0], m_pCurve[1], ccClass) ;
@@ -424,7 +424,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
SwapInfoAB( InfoTmp, 1) ;
// se esiste almeno una intersezione
if ( m_nIntersCount >= 1)
return CalcCurveClassification( m_pCurve[1], InfoTmp, ccClass) ;
return CalcCurveClassification( m_pCurve[1], InfoTmp, dLenMin, ccClass) ;
// altrimenti la curva è completamente interna oppure completamente esterna
else
return CalcCurveInOrOut( m_pCurve[1], m_pCurve[0], ccClass) ;
@@ -461,7 +461,7 @@ IntersCurveCurve::SwapInfoAB( ICCIVECTOR& Info, int IndCrvOrd)
//----------------------------------------------------------------------------
bool
IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTOR& Info, CRVCVECTOR& ccClass)
IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTOR& Info, double dLenMin, CRVCVECTOR& ccClass)
{
// numero intersezioni
int nNumInters = int( Info.size()) ;
@@ -471,6 +471,8 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
double dStartPar, dEndPar ;
if ( pCurve == nullptr || ! pCurve->GetDomain( dStartPar, dEndPar))
return false ;
// limito lunghezza minima
dLenMin = max( dLenMin, EPS_ZERO) ;
// elimino intersezioni senza attraversamento che giacciono in intervalli di sovrapposizione
ICCIVECTOR InfoCorr ;
InfoCorr.reserve( Info.size()) ;
@@ -527,7 +529,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
for ( int i = 0 ; i < nNumInters ; ++ i) {
// se è definito un tratto precedente
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ;
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > EPS_SMALL) {
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
// verifico che la definizione sul tratto sia omogenea e valida
int nPrevTy = InfoCorr[i].IciA[0].nPrevTy ;
if ( ( nLastTy != ICCT_NULL && nPrevTy != nLastTy) ||
@@ -562,7 +564,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
}
}
// eventuale tratto finale rimasto
if ( dCurrPar < dEndPar - EPS_PARAM && dEndLen - dCurrLen > EPS_SMALL) {
if ( dCurrPar < dEndPar - EPS_PARAM && dEndLen - dCurrLen > dLenMin) {
// verifico che la definizione sul tratto sia valida
if ( nLastTy == ICCT_NULL || nLastTy == ICCT_ON)
return false ;
@@ -673,7 +675,7 @@ IntersCurveCurve::GetRegionCurveClassification( void)
{
// classifico la prima curva rispetto alla seconda
CRVCVECTOR ccClass ;
if ( ! GetCurveClassification( 0, ccClass))
if ( ! GetCurveClassification( 0, EPS_SMALL, ccClass))
return CCREGC_NULL ;
// derivo la classificazione delle curve come regioni
bool bIn = false ;
@@ -710,7 +712,7 @@ IntersCurveCurve::GetRegionCurveClassification( void)
if ( bOnP)
return CCREGC_IN2 ;
CRVCVECTOR ccClass2 ;
if ( ! GetCurveClassification( 1, ccClass2) || ccClass2.empty())
if ( ! GetCurveClassification( 1, EPS_SMALL, ccClass2) || ccClass2.empty())
return CCREGC_NULL ;
if ( ccClass2[0].nClass == CRVC_OUT)
return CCREGC_OUT ;
+14 -3
View File
@@ -68,9 +68,20 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
{
// pulisco tutto
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
Plane3d plPlane ;
if ( pCrv == nullptr || ! pCrv->IsFlat( plPlane, false, 10 * EPS_SMALL))
if ( pCrv == nullptr || ! pCrv->IsFlat( plPlane, bIsLine, 10 * EPS_SMALL))
return false ;
// recupero o assegno estrusione
Vector3d vtExtr ;
@@ -449,7 +460,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
inOk.Set( dStart, dEnd) ;
IntersCurveCurve ccInt( *pCrv, *pCircS) ;
CRVCVECTOR ccPart ;
if ( ! ccInt.GetCurveClassification( 0, ccPart))
if ( ! ccInt.GetCurveClassification( 0, EPS_SMALL, ccPart))
return false ;
for ( auto& ccOne : ccPart) {
switch ( ccOne.nClass) {
@@ -498,7 +509,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
inOk.Set( dStart, dEnd) ;
IntersCurveCurve ccInt( *pCrv, *pCircE) ;
CRVCVECTOR ccPart ;
if ( ! ccInt.GetCurveClassification( 0, ccPart))
if ( ! ccInt.GetCurveClassification( 0, EPS_SMALL, ccPart))
return false ;
for ( auto& ccOne : ccPart) {
switch ( ccOne.nClass) {
+223 -5
View File
@@ -22,6 +22,7 @@
#include "/EgtDev/Include/EGkPolyLine.h"
#include "/EgtDev/Include/EGkPlane3d.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EgtNumUtils.h"
using namespace std ;
@@ -829,12 +830,11 @@ PolyLine::MyChangeStart( int nPos)
// solo per polilinee chiuse
if ( ! IsClosed())
return false ;
// cancello ultimo punto ( coincide con primo)
// cancello l'ultimo punto ( coincide con il primo)
m_lUPoints.pop_back() ;
// sposto la metà iniziale dei punti alla fine
for ( int i = 0 ; i < nPos ; ++ i)
m_lUPoints.splice( m_lUPoints.end(), m_lUPoints, m_lUPoints.begin()) ;
// aggiungo punto finale come copia dell'iniziale
// sposto la parte iniziale dei punti alla fine
m_lUPoints.splice( m_lUPoints.end(), m_lUPoints, m_lUPoints.begin(), next( m_lUPoints.begin(), nPos)) ;
// aggiungo il punto finale come copia dell'iniziale
m_lUPoints.push_back( m_lUPoints.front()) ;
return true ;
@@ -1296,3 +1296,221 @@ PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut)
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
View File
@@ -165,7 +165,7 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
for ( auto i : m_vExtInd) {
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
! ccInt.GetCurveClassification( 0, ccClass) ||
! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) ||
ccClass.empty() || ccClass[0].nClass != CRVC_OUT) {
bOk = false ;
break ;
@@ -178,7 +178,7 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
continue ;
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
if ( ccInt.GetCrossOrOverlapIntersCount() == 0 &&
ccInt.GetCurveClassification( 0, ccClass) &&
ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) &&
! ccClass.empty() && ccClass[0].nClass == CRVC_OUT) {
bOk = true ;
break ;
@@ -298,7 +298,7 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[m_vExtInd[i]]) ;
CRVCVECTOR ccClass ;
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
! ccInt.GetCurveClassification( 0, ccClass) ||
! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) ||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
continue ;
// verifica rispetto ai loop interni
@@ -309,7 +309,7 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
IntersCurveCurve ccInt2( *pMyCrv, *m_vpLoop[k]) ;
CRVCVECTOR ccClass2 ;
if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 ||
! ccInt2.GetCurveClassification( 0, ccClass2) ||
! ccInt2.GetCurveClassification( 0, EPS_SMALL, ccClass2) ||
ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) {
bOk = false ;
break ;
@@ -1150,7 +1150,7 @@ SurfFlatRegion::CloneChunk( int nChunk) const
//----------------------------------------------------------------------------
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
// verifico lo stato
@@ -1179,7 +1179,7 @@ SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass
IntersCurveCurve ccInt( Crv, *pLoop) ;
// classificazione
CRVCVECTOR ccPart ;
if ( ! ccInt.GetCurveClassification( 0, ccPart))
if ( ! ccInt.GetCurveClassification( 0, dLenMin, ccPart))
return false ;
for ( auto& ccOne : ccPart) {
switch ( ccOne.nClass) {
@@ -1272,7 +1272,7 @@ SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass
//----------------------------------------------------------------------------
bool
SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const
SurfFlatRegion::GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const
{
// verifico lo stato
if ( m_nStatus != OK || m_vpLoop.empty())
@@ -1293,7 +1293,7 @@ SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass)
pCrvLoc = pCopyCrv ;
}
// esecuzione classificazione nel riferimento intrinseco
return MyGetCurveClassification( *pCrvLoc, ccClass) ;
return MyGetCurveClassification( *pCrvLoc, dLenMin, ccClass) ;
}
//----------------------------------------------------------------------------
+2 -2
View File
@@ -92,7 +92,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
const SurfTriMesh* GetAuxSurf( void) const override ;
SurfFlatRegion* CloneChunk( int nChunk) 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
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)
void ResetAuxSurf( void) const ;
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,
int nType1, bool bInvert1, int nType2, bool bInvert2, PCRV_DEQUE& vpCurve) ;
static bool MyChainCurves( PCRV_DEQUE& vpCurve, PCRV_DEQUE& vpLoop) ;
+2 -2
View File
@@ -289,7 +289,7 @@ SurfFlatRegion::MySelectCurves( const PCRV_DEQUE& vpLoop, const SurfFlatRegion&
for ( auto& pLoop : vpLoop) {
// eseguo classificazione
CRVCVECTOR ccClass ;
if ( ! Other.MyGetCurveClassification( *pLoop, ccClass))
if ( ! Other.MyGetCurveClassification( *pLoop, EPS_SMALL, ccClass))
return false ;
// creo intervalli validi, tenendo classificazioni ricevute
Intervals inOk1( EPS_PARAM), inOk2( EPS_PARAM) ;
@@ -441,7 +441,7 @@ SurfFlatRegion::MyNewSurfFromLoops( PCRV_DEQUE& vpLoop)
CRVCVECTOR ccClass ;
IntersCurveCurve ccInt( *vpLoop[l], *pExtLoop) ;
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
! ccInt.GetCurveClassification( 0, ccClass) ||
! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) ||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
continue ;
// lo inserisco
+76 -39
View File
@@ -3401,11 +3401,9 @@ SurfTriMesh::Invert( void)
//----------------------------------------------------------------------------
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)
return false ;
@@ -3430,7 +3428,6 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
++ m_nTimeStamp ;
// sistemo i triangoli (eventualmente li elimino)
bool bModif = false ;
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
// salto i triangoli cancellati e quelli aggiunti
if ( m_vTria[i].nIdVert[0] == SVT_DEL || m_vTria[i].nTemp == m_nTimeStamp)
@@ -3609,43 +3606,40 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
}
}
// se effettuate modifiche
if ( bModif) {
// aggiorno tutto
if ( ! AdjustVertices() || ! DoCompacting())
return false ;
}
return true ;
}
#else
bool bModif = false ;
// Setto i triangoli come né fuori né dentro.
int nTriaNum = GetTriangleSize() ;
for ( int nT = 0 ; nT < nTriaNum ; ++ nT) {
//----------------------------------------------------------------------------
bool
SurfTriMesh::CutByFacets( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif)
{
// Setto posizione triangoli non definita
for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT)
m_vTria[nT].nTempPart = 0 ;
}
INTERSCHAINMAP IntersLineMap ;
// Ciclo su tutte le facce.
int nFacetNum = GetFacetCount() ;
for ( int nF = 0 ; nF < nFacetNum ; ++ nF) {
for ( int nF = 0 ; nF < GetFacetCount() ; ++ nF) {
// Dati della faccia
POLYLINEVECTOR vLoopVec ;
GetFacetLoops( nF, vLoopVec) ;
if ( vLoopVec.empty())
continue ;
PtrOwner<SurfFlatRegion> pReg( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( vLoopVec))) ;
if ( IsNull( pReg))
return false ;
// Verifico la posizione del loop esterno
int nIntType = VerifyLoopPlane( vLoopVec[0], plPlane) ;
// Se interseca il piano di taglio, calcolo la divisione della faccia
LineFacetClassVector IntersLinePart ;
int nIntType = IntersFacetPlane( *pReg, vLoopVec[0], plPlane, IntersLinePart) ;
if ( nIntType == FacetPlaneIntersType::FPI_CUT) {
if ( nIntType == 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) {
// Salvo intersezione per la faccia.
// Salvo intersezione per la faccia.
auto it = IntersLineMap.find( nF) ;
if ( it != IntersLineMap.end()) {
it->second.emplace_back( IntersInnSeg( IntersLinePart[nPart].ptSt, IntersLinePart[nPart].ptEn)) ;
@@ -3655,26 +3649,28 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
}
}
}
else if ( nIntType == FacetPlaneIntersType::FPI_ON) {
else if ( nIntType == FPI_ON) {
INTVECTOR vT ;
GetAllTriaInFacet( nF, vT) ;
Vector3d vtNf ;
GetFacetNormal( nF, vtNf) ;
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 ;
GetAllTriaInFacet( nF, vT) ;
for ( auto& nT : vT)
m_vTria[nT].nTempPart = 1 ;
}
else if ( nIntType == FacetPlaneIntersType::FPI_OUT) {
else if ( nIntType == FPI_OUT) {
INTVECTOR vT ;
GetAllTriaInFacet( nF, vT) ;
for ( auto& nT : vT)
m_vTria[nT].nTempPart = - 1 ;
m_vTria[nT].nTempPart = -1 ;
}
else
;
return false ;
}
// Divido le facce.
@@ -3683,13 +3679,54 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
INTERSEDGEMAP EdgeInterLineMap, EdgeEdgeLineMap ;
RetriangulateFacetPieces( NewFacet, EdgeInterLineMap, EdgeEdgeLineMap) ;
int nNumTria = GetTriangleSize() ;
for ( int nT = 0 ; nT < nNumTria ; ++ nT)
if ( m_vTria[nT].nTempPart == - 1 || m_vTria[nT].nTempPart == - 2 || ( ! bSaveOnEq && m_vTria[nT].nTempPart == 2))
// Elimino i triangoli superflui
for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT) {
if ( m_vTria[nT].nTempPart == 0 ||
m_vTria[nT].nTempPart == -1 ||
m_vTria[nT].nTempPart == -2 ||
( ! bSaveOnEq && m_vTria[nT].nTempPart == 2)) {
RemoveTriangle( nT) ;
bModif = true ;
}
}
return AdjustVertices() && DoCompacting() ;
#endif
return true ;
}
//----------------------------------------------------------------------------
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 ;
}
//----------------------------------------------------------------------------
+9 -5
View File
@@ -121,7 +121,7 @@ struct LineFacetClass {
nTypeA = 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 ;
ptEn = ptE ;
nTypeA = nTpA ;
@@ -131,7 +131,7 @@ struct LineFacetClass {
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
@@ -381,19 +381,23 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
void ResetHashGrids3d( void) const ;
bool VerifyHashGrids3d( 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 RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf, bool& bModif) ;
bool AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf) ;
bool IntersectTriMeshTriangle( SurfTriMesh& Other) ;
int IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& ExtLoop, const Plane3d& plCutPlane,
LineFacetClassVector& IntersLinePart) ;
int VerifyLoopPlane( const PolyLine& ExtLoop, const Plane3d& plCutPlane) ;
int IntersFacetPlane( const SurfFlatRegion& Region, const Plane3d& plCutPlane,
LineFacetClassVector& IntersLinePart) ;
bool IntersFacetFacet( const SurfFlatRegion& RegionA, const PolyLine& ExtLoopA,
const SurfFlatRegion& RegionB, const PolyLine& ExtLoopB,
LineFacetClassVector& IntersLinePart) ;
bool ItersectTriMeshFacets( SurfTriMesh& Other) ;
bool IntersectTriMeshFacets( SurfTriMesh& Other) ;
bool RetriangulateFacetPieces( const PieceMap& NewFacet,
const INTERSEDGEMAP& EdgeInterLineMap,
const INTERSEDGEMAP& EdgeEdgeLineMap) ;
bool SimplifyFacets( double dMaxEdgeLen) ;
bool EdgeInteriorContactManager( const SurfTriMesh& OthSurf,
const INTERSCHAINMAP& InterInterLineMap,
const INTERSEDGEMAP& EdgeInterLineMap) ;
+498 -901
View File
File diff suppressed because it is too large Load Diff
+250
View File
@@ -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
View File
@@ -220,7 +220,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
// Determino le intersezioni della retta con la regione
CRVCVECTOR IntersectionResults ;
Surf.GetCurveClassification( GridLine, IntersectionResults) ;
Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ;
// Analizzo le parti in cui la retta è stata divisa
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
CRVCVECTOR IntersectionResults ;
Surf.GetCurveClassification( GridLine, IntersectionResults) ;
Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ;
// Analizzo le parti
int nPart = int( IntersectionResults.size()) ;