EgtGeomKernel 1.6h3 :
- migliorata approssimazione curve per riconoscimento di tratti rettilinei - aggiunta CopyMaterial a GeomDB - correzioni a IntersCurveCurve per le curve approssimate - aggiunte a Intervals Union, Intersection e Difference - correzioni a SelfIntersCurve per curve approssimate - aggiunte funzioni di creazione Regioni (Rectangle, Stadium, Disk e da zuppa di curve) - migliorie varie a Regioni e introduzione dei componenti connessi (chunk).
This commit is contained in:
+1
-1
@@ -73,7 +73,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
}
|
||||
|
||||
// se il biarco non esiste
|
||||
if ( pBiArc->GetCurveNumber() == 0)
|
||||
if ( pBiArc->GetCurveCount() == 0)
|
||||
return nullptr ;
|
||||
|
||||
return ::Release( pBiArc) ;
|
||||
|
||||
@@ -100,6 +100,8 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
{ return ::GetNearestExtremityToPoint( ptP, *this, bStart) ; }
|
||||
virtual bool GetAreaXY( double& dArea) const
|
||||
{ return CurveGetAreaXY( *this, dArea) ; }
|
||||
virtual bool GetArea( Plane3d& plPlane, double& dArea) const
|
||||
{ return CurveGetArea( *this, plPlane, dArea) ; }
|
||||
virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const ;
|
||||
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
|
||||
virtual bool ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA) const
|
||||
|
||||
@@ -259,6 +259,33 @@ GetPointDiffGeom( const ICurve& crvC, double dU, ICurve::Side nS, CrvPointDiffGe
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ImproveCurveParamAtPoint( double& dU, const Point3d& ptP, const ICurve* pCrv)
|
||||
{
|
||||
// Da usare quando il parametro è già molto vicino a quello esatto
|
||||
|
||||
// calcolo il punto della curva in corrispondenza al parametro
|
||||
Point3d ptQ ;
|
||||
Vector3d vtD ;
|
||||
if ( ! pCrv->GetPointD1D2( dU, ICurve::FROM_MINUS, ptQ, &vtD))
|
||||
return false ;
|
||||
// se sono uguali, è già tutto ok
|
||||
if ( AreSamePointExact( ptP, ptQ))
|
||||
return true ;
|
||||
// se derivata nulla, non posso migliorare
|
||||
if ( vtD.IsZero())
|
||||
return false ;
|
||||
// incremento parametro su linea tangente (uso la derivata)
|
||||
double dDeltaU = ( ptP - ptQ) * vtD / vtD.SqLen() ;
|
||||
// se migliorato, tengo nuovo valore
|
||||
Point3d ptR ;
|
||||
if ( pCrv->GetPointD1D2( dU + dDeltaU, ICurve::FROM_MINUS, ptR) &&
|
||||
( ptP - ptR).SqLen() < ( ptP - ptQ).SqLen())
|
||||
dU += dDeltaU ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveGetAreaXY( const ICurve& crvC, double& dArea)
|
||||
@@ -278,6 +305,29 @@ CurveGetAreaXY( const ICurve& crvC, double& dArea)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea)
|
||||
{
|
||||
// verifico sia chiusa
|
||||
if ( ! crvC.IsClosed())
|
||||
return false ;
|
||||
// approssimo la curva con una polilinea
|
||||
PolyLine PL ;
|
||||
crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) ;
|
||||
// calcolo l'area
|
||||
Plane3d plMyPlane ;
|
||||
double dMyArea = 0 ;
|
||||
if ( ! PL.IsClosedAndFlat( plMyPlane, dMyArea, 50 * EPS_SMALL))
|
||||
return false ;
|
||||
// restituisco i valori
|
||||
if ( &plPlane != nullptr)
|
||||
plPlane = plMyPlane ;
|
||||
if ( &dArea != nullptr)
|
||||
dArea = dMyArea ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveDump( const ICurve& crvC, string& sOut, bool bMM, const char* szNewLine)
|
||||
@@ -646,4 +696,42 @@ NurbsToBezierCurve( const CNurbsData& cnData)
|
||||
|
||||
// restituisco la curva composita
|
||||
return Release( pCrvCompo) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
ProjectCurveOnPlane( const ICurve& crCrv, const Plane3d& plPlane)
|
||||
{
|
||||
// determino se curva piana e suo eventuale piano
|
||||
Plane3d plCrv ;
|
||||
if ( crCrv.IsFlat( plCrv)) {
|
||||
// se il piano della curva è parallelo a quello di proiezione
|
||||
if ( AreSameOrOppositeVectorApprox( plCrv.vtN, plPlane.vtN)) {
|
||||
// copio la curva
|
||||
PtrOwner<ICurve> pCrv( crCrv.Clone()) ;
|
||||
if ( IsNull( pCrv))
|
||||
return nullptr ;
|
||||
// se non coincidenti, basta eseguire una traslazione
|
||||
Point3d ptOC = ORIG + plCrv.dDist * plCrv.vtN ;
|
||||
Point3d ptOP = ORIG + plPlane.dDist * plPlane.vtN ;
|
||||
if ( ! AreSamePointApprox( ptOC, ptOP))
|
||||
pCrv->Translate( ptOP - ptOC) ;
|
||||
// restituisco la nuova curva
|
||||
return Release( pCrv) ;
|
||||
}
|
||||
}
|
||||
|
||||
// mi assicuro che la curva non contenga archi
|
||||
PtrOwner<ICurve> pCrv( CurveToNoArcsCurve( &crCrv)) ;
|
||||
if ( IsNull( pCrv))
|
||||
return nullptr ;
|
||||
// calcolo un riferimento con piano XY coincidente con il piano di proiezione
|
||||
Frame3d frRef ;
|
||||
if ( ! frRef.Set( ORIG + plPlane.dDist * plPlane.vtN, plPlane.vtN))
|
||||
return nullptr ;
|
||||
// eseguo scalatura con fattori X e Y unitari e fattore Z nullo
|
||||
if ( ! pCrv->Scale( frRef, 1, 1, 0))
|
||||
return nullptr ;
|
||||
// restituisco la nuova curva
|
||||
return Release( pCrv) ;
|
||||
}
|
||||
@@ -25,7 +25,9 @@ bool MoveParamToAvoidTg( double& dU, ICurve::Side nSide, const ICurve& Curve) ;
|
||||
bool GetTang( const ICurve& crvC, double dU, ICurve::Side nS, Vector3d& vtTang) ;
|
||||
bool GetPointTang( const ICurve& crvC, double dU, ICurve::Side nS, Point3d& ptPos, Vector3d& vtTang) ;
|
||||
bool GetPointDiffGeom( const ICurve& crvC, double dU, ICurve::Side nS, CrvPointDiffGeom& oDiffG) ;
|
||||
bool ImproveCurveParamAtPoint( double& dU, const Point3d& ptP, const ICurve* pCrv) ;
|
||||
bool CurveGetAreaXY( const ICurve& crvC, double& dArea) ;
|
||||
bool CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea) ;
|
||||
bool CurveDump( const ICurve& crvC, std::string& sOut, bool bMM, const char* szNewLine) ;
|
||||
bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||
bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||
|
||||
@@ -60,7 +60,6 @@ CurveBezier::~CurveBezier( void)
|
||||
bool
|
||||
CurveBezier::Init( int nDeg, bool bIsRational)
|
||||
{
|
||||
|
||||
// verifico validità grado
|
||||
if ( nDeg < 1 || nDeg > MAXDEG)
|
||||
return false ;
|
||||
|
||||
@@ -101,6 +101,8 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
{ return ::GetNearestExtremityToPoint( ptP, *this, bStart) ; }
|
||||
virtual bool GetAreaXY( double& dArea) const
|
||||
{ return CurveGetAreaXY( *this, dArea) ; }
|
||||
virtual bool GetArea( Plane3d& plPlane, double& dArea) const
|
||||
{ return CurveGetArea( *this, plPlane, dArea) ; }
|
||||
virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const ;
|
||||
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
|
||||
virtual bool ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA) const
|
||||
|
||||
+37
-19
@@ -82,6 +82,10 @@ CurveByApprox::GetArcs( double dLinTol, double dAngTolDeg, double dLinFea, PolyA
|
||||
// pulisco il poliarco
|
||||
PA.Clear() ;
|
||||
|
||||
// calcolo una parametrizzazione
|
||||
if ( ! CalcParameterization())
|
||||
return false ;
|
||||
|
||||
// calcolo le tangenti
|
||||
if ( ! CalcAkimaTangents( true))
|
||||
return false ;
|
||||
@@ -109,12 +113,10 @@ CurveByApprox::GetArcs( double dLinTol, double dAngTolDeg, double dLinFea, PolyA
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveByApprox::CalcAkimaTangents( bool bDetectCorner)
|
||||
CurveByApprox::CalcParameterization( void)
|
||||
{
|
||||
// pulisco i vettori dei parametri e delle tangenti
|
||||
// pulisco il vettore dei parametri
|
||||
m_vPar.clear() ;
|
||||
m_vPrevDer.clear() ;
|
||||
m_vNextDer.clear() ;
|
||||
|
||||
// numero di punti
|
||||
int nSize = int( m_vPnt.size()) ;
|
||||
@@ -133,6 +135,24 @@ CurveByApprox::CalcAkimaTangents( bool bDetectCorner)
|
||||
m_vPar.push_back( dPar) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveByApprox::CalcAkimaTangents( bool bDetectCorner)
|
||||
{
|
||||
// pulisco i vettori delle tangenti
|
||||
m_vPrevDer.clear() ;
|
||||
m_vNextDer.clear() ;
|
||||
|
||||
// numero di punti
|
||||
int nSize = int( m_vPnt.size()) ;
|
||||
|
||||
// sono necessari almeno due punti
|
||||
if ( nSize < 2)
|
||||
return false ;
|
||||
|
||||
// calcolo le derivate
|
||||
m_vPrevDer.reserve( nSize) ;
|
||||
m_vNextDer.reserve( nSize) ;
|
||||
@@ -254,8 +274,7 @@ CurveByApprox::CalcAkimaTangents( bool bDetectCorner)
|
||||
bool
|
||||
CurveByApprox::CalcBesselTangents( void)
|
||||
{
|
||||
// pulisco i vettori dei parametri e delle tangenti
|
||||
m_vPar.clear() ;
|
||||
// pulisco i vettori delle tangenti
|
||||
m_vPrevDer.clear() ;
|
||||
m_vNextDer.clear() ;
|
||||
|
||||
@@ -266,16 +285,6 @@ CurveByApprox::CalcBesselTangents( void)
|
||||
if ( nSize < 2)
|
||||
return false ;
|
||||
|
||||
// calcolo le distanze tra i punti per derivarne i parametri
|
||||
m_vPar.reserve( nSize) ;
|
||||
double dPar = 0 ;
|
||||
m_vPar.push_back( dPar) ;
|
||||
for ( int i = 1 ; i < nSize ; ++ i) {
|
||||
double dDist = Dist( m_vPnt[i-1], m_vPnt[i]) ;
|
||||
dPar += dDist ;
|
||||
m_vPar.push_back( dPar) ;
|
||||
}
|
||||
|
||||
// calcolo le derivate
|
||||
m_vPrevDer.reserve( nSize) ;
|
||||
m_vNextDer.reserve( nSize) ;
|
||||
@@ -349,24 +358,33 @@ CurveByApprox::CalcSplitPoints( double dLinTol, double dAngTolDeg, double dLinFe
|
||||
// precalcolo funzioni dei limiti
|
||||
double dSqLinTol = dLinTol * dLinTol ;
|
||||
double dAngTolCos = cos( max( dAngTolDeg, 0.) * DEGTORAD) ;
|
||||
double d2AngTolCos = cos( max( 2 * dAngTolDeg, 0.) * DEGTORAD) ;
|
||||
double dSqLinFea = dLinFea * dLinFea ;
|
||||
// cerco punti angolosi e punti di separazione di tratti lineari e non
|
||||
// verifico i punti tranne primo e ultimo
|
||||
int nSize = int( m_vPnt.size()) ;
|
||||
for ( int i = 1 ; i < nSize - 1 ; ++ i) {
|
||||
// se angolo, allora punto di divisione
|
||||
// se stimato angolo, allora punto di divisione
|
||||
if ( ( m_vPrevDer[i] * m_vNextDer[i]) < dAngTolCos) {
|
||||
m_vSplits.push_back(i) ;
|
||||
continue ;
|
||||
}
|
||||
// verifico linearità del tratto precedente
|
||||
// dati sui segmenti precedente e successivo
|
||||
Vector3d vtPrev = m_vPnt[i] - m_vPnt[i-1] ;
|
||||
double dLenPrev = m_vPar[i] - m_vPar[i-1] ;
|
||||
Vector3d vtNext = m_vPnt[i+1] - m_vPnt[i] ;
|
||||
double dLenNext = m_vPar[i+1] - m_vPar[i] ;
|
||||
// se i segmenti formano un angolo maggiore del doppio ammesso, allora punto di divisione
|
||||
if ( ( vtPrev * vtNext) / ( dLenPrev * dLenNext) < d2AngTolCos) {
|
||||
m_vSplits.push_back(i) ;
|
||||
continue ;
|
||||
}
|
||||
// verifico linearità del tratto precedente
|
||||
bool bPrevLin = vtPrev.SqLen() > dSqLinFea &&
|
||||
( m_vNextDer[i-1] * m_vPrevDer[i]) > dAngTolCos &&
|
||||
( vtPrev ^ m_vNextDer[i-1]).SqLen() < dSqLinTol &&
|
||||
( vtPrev ^ m_vPrevDer[i]).SqLen() < dSqLinTol ;
|
||||
// verifico linearità del tratto successivo
|
||||
Vector3d vtNext = m_vPnt[i+1] - m_vPnt[i] ;
|
||||
bool bNextLin = vtNext.SqLen() > dSqLinFea &&
|
||||
( m_vNextDer[i] * m_vPrevDer[i+1]) > dAngTolCos &&
|
||||
( vtNext ^ m_vNextDer[i]).SqLen() < dSqLinTol &&
|
||||
|
||||
+3
-1
@@ -96,6 +96,8 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
{ return ::GetNearestExtremityToPoint( ptP, *this, bStart) ; }
|
||||
virtual bool GetAreaXY( double& dArea) const
|
||||
{ return CurveGetAreaXY( *this, dArea) ; }
|
||||
virtual bool GetArea( Plane3d& plPlane, double& dArea) const
|
||||
{ return CurveGetArea( *this, plPlane, dArea) ; }
|
||||
virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const ;
|
||||
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
|
||||
virtual bool ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA) const ;
|
||||
@@ -128,7 +130,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
virtual bool PolygonCenterCorner( int nSides, const Point3d& ptCen, const Point3d& ptCorner, const Vector3d& vtN) ;
|
||||
virtual bool PolygonCenterMidSide( int nSides, const Point3d& ptCen, const Point3d& ptMidSide, const Vector3d& vtN) ;
|
||||
virtual bool PolygonSide( int nSides, const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtN) ;
|
||||
virtual int GetCurveNumber( void) const
|
||||
virtual int GetCurveCount( void) const
|
||||
{ return int( m_CrvSmplS.size()) ; }
|
||||
virtual const ICurve* GetCurve( int nCrv) const ;
|
||||
virtual const ICurve* GetFirstCurve( void) const ;
|
||||
|
||||
@@ -104,7 +104,7 @@ CurveComposite::SimpleOffsetXY( double dDist, int nType)
|
||||
if ( VerifyAndAdjustSamePoint( pCrv1, pCrv2, ccTemp) ||
|
||||
VerifyAndAdjustInternalAngle( pCrv1, pCrv2, ccTemp) ||
|
||||
VerifyAndAdjustExternalAngle( pCrv1, pCrv2, dDist, nType, ccTemp)) {
|
||||
if ( ccTemp.GetCurveNumber() > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
|
||||
if ( ccTemp.GetCurveCount() > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
|
||||
return false ;
|
||||
}
|
||||
// nessun caso è andato a buon fine, errore
|
||||
@@ -120,7 +120,7 @@ CurveComposite::SimpleOffsetXY( double dDist, int nType)
|
||||
}
|
||||
|
||||
// se originale chiuso, devo confrontare anche ultima e prima curva
|
||||
if ( bClosed && ccOffs.GetCurveNumber() > 0) {
|
||||
if ( bClosed && ccOffs.GetCurveCount() > 0) {
|
||||
// la curva successiva ora è la prima dell'offset
|
||||
ICurve* pCrv2 = ccOffs.m_CrvSmplS.front() ;
|
||||
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
|
||||
@@ -128,7 +128,7 @@ CurveComposite::SimpleOffsetXY( double dDist, int nType)
|
||||
if ( VerifyAndAdjustSamePoint( pCrv1, pCrv2, ccTemp) ||
|
||||
VerifyAndAdjustInternalAngle( pCrv1, pCrv2, ccTemp) ||
|
||||
VerifyAndAdjustExternalAngle( pCrv1, pCrv2, dDist, nType, ccTemp)) {
|
||||
if ( ccTemp.GetCurveNumber() > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
|
||||
if ( ccTemp.GetCurveCount() > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
|
||||
return false ;
|
||||
}
|
||||
// nessun caso è andato a buon fine, errore
|
||||
@@ -137,7 +137,7 @@ CurveComposite::SimpleOffsetXY( double dDist, int nType)
|
||||
}
|
||||
|
||||
// se originale aperto, devo rimettere eventuali lineee verticali iniziale e finale
|
||||
if ( ! bClosed && ccOffs.GetCurveNumber() > 0 &&
|
||||
if ( ! bClosed && ccOffs.GetCurveCount() > 0 &&
|
||||
! AddFirstLastVerticalLines( ccOffs, dLenVertFirst, dLenVertLast))
|
||||
return false ;
|
||||
|
||||
|
||||
@@ -101,6 +101,8 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
{ return ::GetNearestExtremityToPoint( ptP, *this, bStart) ; }
|
||||
virtual bool GetAreaXY( double& dArea) const
|
||||
{ return false ; }
|
||||
virtual bool GetArea( Plane3d& plPlane, double& dArea) const
|
||||
{ return false ; }
|
||||
virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const ;
|
||||
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
|
||||
virtual bool ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA) const
|
||||
|
||||
Binary file not shown.
@@ -321,6 +321,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="NgeReader.cpp" />
|
||||
<ClCompile Include="FontOs.cpp" />
|
||||
<ClCompile Include="SelfIntersCurve.cpp" />
|
||||
<ClCompile Include="SfrCreate.cpp" />
|
||||
<ClCompile Include="SurfFlatRegion.cpp" />
|
||||
<ClCompile Include="UserObjDefault.cpp" />
|
||||
<ClCompile Include="UserObjFactory.cpp" />
|
||||
@@ -400,9 +401,11 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="..\Include\EGkPolyArc.h" />
|
||||
<ClInclude Include="..\Include\EGkPolyLine.h" />
|
||||
<ClInclude Include="..\Include\EGkSelection.h" />
|
||||
<ClInclude Include="..\Include\EGkSfrCreate.h" />
|
||||
<ClInclude Include="..\Include\EGkStmFromCurves.h" />
|
||||
<ClInclude Include="..\Include\EGkStmStandard.h" />
|
||||
<ClInclude Include="..\Include\EGkStringUtils3d.h" />
|
||||
<ClInclude Include="..\Include\EGkSurfFlatRegion.h" />
|
||||
<ClInclude Include="..\Include\EgkSurfTriMesh.h" />
|
||||
<ClInclude Include="..\Include\EGkTriangle3d.h" />
|
||||
<ClInclude Include="..\Include\EGkUserObj.h" />
|
||||
|
||||
@@ -303,6 +303,9 @@
|
||||
<ClCompile Include="SurfFlatRegion.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SfrCreate.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -695,6 +698,12 @@
|
||||
<ClInclude Include="SurfFlatRegion.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkSurfFlatRegion.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkSfrCreate.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+3
-3
@@ -5008,7 +5008,7 @@ GdbExecutor::CurveCopyBySplitClass( const STRVECTOR& vsParams)
|
||||
return false ;
|
||||
// verifico anche che non si autointersechi con attraversamento
|
||||
SelfIntersCurve sintC( *pCloCrv) ;
|
||||
if ( sintC.GetNumCrossInters() > 0)
|
||||
if ( sintC.GetCrossIntersCount() > 0)
|
||||
return false ;
|
||||
// recupero i riferimenti in cui sono immerse
|
||||
Frame3d frCrv ;
|
||||
@@ -5156,10 +5156,10 @@ GdbExecutor::CurveCopyByChain( const STRVECTOR& vsParams)
|
||||
return false ;
|
||||
}
|
||||
// aggiorno il nuovo punto vicino
|
||||
if ( pCrvCompo->GetCurveNumber() > 0)
|
||||
if ( pCrvCompo->GetCurveCount() > 0)
|
||||
pCrvCompo->GetEndPoint( ptNearStart) ;
|
||||
// inserisco la curva composita nel gruppo destinazione
|
||||
if ( pCrvCompo->GetCurveNumber() > 0) {
|
||||
if ( pCrvCompo->GetCurveCount() > 0) {
|
||||
if ( m_pGDB->AddGeoObj( GDB_ID_NULL, nIdDest, ::Release( pCrvCompo)) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
|
||||
@@ -653,6 +653,10 @@ GdbObj::SetMaterial( int nMat)
|
||||
if ( nMat < GDB_MT_PARENT)
|
||||
return false ;
|
||||
|
||||
// se materiale da padre e non ci sono attributi è già così
|
||||
if ( nMat == GDB_MT_PARENT && GetAttribs() == nullptr)
|
||||
return true ;
|
||||
|
||||
// verifico esistenza (con eventuale creazione) degli attributi
|
||||
if ( GetSafeAttribs() == nullptr)
|
||||
return false ;
|
||||
|
||||
+53
@@ -2061,6 +2061,59 @@ GeomDB::GetCalcMark( int nId, int& nMark) const
|
||||
return pGdbObj->GetCalcMark( nMark) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::CopyMaterial( int nIdSou, int nIdDest)
|
||||
{
|
||||
// verifico esistenza del sorgente
|
||||
GdbObj* pGdOSou = GetGdbObj( nIdSou) ;
|
||||
if ( pGdOSou == nullptr)
|
||||
return false ;
|
||||
// verifico esistenza della destinazione
|
||||
GdbObj* pGdODest = GetGdbObj( nIdDest) ;
|
||||
if ( pGdODest == nullptr)
|
||||
return false ;
|
||||
// recupero l'indice del materiale
|
||||
int nMat ;
|
||||
if ( ! pGdOSou->GetMaterial( nMat))
|
||||
nMat = GDB_MT_PARENT ;
|
||||
// impostazione
|
||||
switch ( nMat) {
|
||||
case GDB_MT_COLOR :
|
||||
{
|
||||
Color cCol ;
|
||||
if ( ! pGdOSou->GetMaterial( cCol))
|
||||
GetDefaultMaterial( cCol) ;
|
||||
pGdODest->SetMaterial( cCol) ;
|
||||
}
|
||||
break ;
|
||||
case GDB_MT_PARENT :
|
||||
// hanno lo stesso padre
|
||||
if ( pGdOSou->GetParentId() == pGdODest->GetParentId())
|
||||
pGdODest->SetMaterial( nMat) ;
|
||||
// altrimenti hanno padre diverso
|
||||
else {
|
||||
// recupero indice calcolato
|
||||
pGdOSou->GetCalcMaterial( nMat) ;
|
||||
// se diverso da colore, lo posso assegnare direttamente
|
||||
if ( nMat != GDB_MT_COLOR)
|
||||
pGdODest->SetMaterial( nMat) ;
|
||||
// altrimenti devo calcolare il colore e assegnarlo
|
||||
else {
|
||||
Color cCol ;
|
||||
if ( ! pGdOSou->GetCalcMaterial( cCol))
|
||||
GetDefaultMaterial( cCol) ;
|
||||
pGdODest->SetMaterial( cCol) ;
|
||||
}
|
||||
}
|
||||
break ;
|
||||
default :
|
||||
pGdODest->SetMaterial( nMat) ;
|
||||
break ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::SetDefaultMaterial( Color cCol)
|
||||
|
||||
@@ -138,6 +138,7 @@ class GeomDB : public IGeomDB
|
||||
virtual bool ResetMark( int nId) ;
|
||||
virtual bool GetMark( int nId, int& nMark) const ;
|
||||
virtual bool GetCalcMark( int nId, int& nMark) const ;
|
||||
virtual bool CopyMaterial( int nIdSou, int nIdDest) ;
|
||||
virtual bool SetDefaultMaterial( Color cCol) ;
|
||||
virtual bool GetDefaultMaterial( Color& cCol) const ;
|
||||
virtual bool SetMaterial( int nId, int nMat) ;
|
||||
|
||||
@@ -60,8 +60,8 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
|
||||
// creo HashGrids2d per curva con maggior numero di elementi
|
||||
const int LIM_CRVNBRSQUARED = 4095 ;
|
||||
int nCrvNbrA = CCompoA.GetCurveNumber() ;
|
||||
int nCrvNbrB = CCompoB.GetCurveNumber() ;
|
||||
int nCrvNbrA = CCompoA.GetCurveCount() ;
|
||||
int nCrvNbrB = CCompoB.GetCurveCount() ;
|
||||
if ( nCrvNbrA >= nCrvNbrB) {
|
||||
HashGrids2d HHGrids ;
|
||||
HHGrids.SetActivationGrid( nCrvNbrA * nCrvNbrB > LIM_CRVNBRSQUARED) ;
|
||||
|
||||
+62
-39
@@ -1,13 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
// EgalTech 2015-2015
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersCurveCurve.cpp Data : 20.06.14 Versione : 1.5f6
|
||||
// File : IntersCurveCurve.cpp Data : 17.08.15 Versione : 1.6h3
|
||||
// Contenuto : Implementazione della classe intersezione curva/curva.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 15.06.14 DS Creazione modulo.
|
||||
//
|
||||
// 17.08.15 DS Modifiche per curve approssimate.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -37,71 +37,78 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
||||
// inizializzazioni
|
||||
m_bOverlaps = false ;
|
||||
m_nNumInters = 0 ;
|
||||
m_pOriCrv[0] = &CurveA ;
|
||||
m_pOriCrv[1] = &CurveB ;
|
||||
m_pCurve[0] = &CurveA ;
|
||||
m_pCurve[1] = &CurveB ;
|
||||
|
||||
// puntatori alle curve usate nei calcoli (originali o temporanee)
|
||||
const ICurve* pCalcCrv[2] ;
|
||||
// per eventuale esplosione temporanea delle curve
|
||||
PtrOwner<ICurve> pTmpCrv[2] ;
|
||||
|
||||
// ciclo sulle curve per verificare se da approssimare
|
||||
for ( int i = 0 ; i < 2 ; ++ i) {
|
||||
// se curva è arco da approssimare oppure è curva di Bezier
|
||||
if ( ( m_pOriCrv[i]->GetType() == CRV_ARC && IsArcToApprox( *m_pOriCrv[i])) ||
|
||||
m_pOriCrv[i]->GetType() == CRV_BEZ) {
|
||||
if ( ( m_pCurve[i]->GetType() == CRV_ARC && IsArcToApprox( *m_pCurve[i])) ||
|
||||
m_pCurve[i]->GetType() == CRV_BEZ) {
|
||||
// approssimo con rette
|
||||
PolyLine PL ;
|
||||
if ( ! m_pOriCrv[i]->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
if ( ! m_pCurve[i]->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
return ;
|
||||
m_pTmpCrv[i].Set( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( m_pTmpCrv[i]))
|
||||
pTmpCrv[i].Set( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pTmpCrv[i]))
|
||||
return ;
|
||||
if ( ! GetBasicCurveComposite( Get( m_pTmpCrv[i]))->FromPolyLine( PL))
|
||||
if ( ! GetBasicCurveComposite( Get( pTmpCrv[i]))->FromPolyLine( PL))
|
||||
return ;
|
||||
m_pCurve[i] = Get( m_pTmpCrv[i]) ;
|
||||
pCalcCrv[i] = Get( pTmpCrv[i]) ;
|
||||
}
|
||||
else
|
||||
m_pCurve[i] = m_pOriCrv[i] ;
|
||||
pCalcCrv[i] = m_pCurve[i] ;
|
||||
}
|
||||
|
||||
// chiamo calcolatore opportuno
|
||||
switch ( m_pCurve[0]->GetType()) {
|
||||
switch ( pCalcCrv[0]->GetType()) {
|
||||
case CRV_LINE :
|
||||
switch ( m_pCurve[1]->GetType()) {
|
||||
switch ( pCalcCrv[1]->GetType()) {
|
||||
case CRV_LINE :
|
||||
LineLineCalculate( *m_pCurve[0], *m_pCurve[1], bAreSegments) ;
|
||||
LineLineCalculate( *pCalcCrv[0], *pCalcCrv[1], bAreSegments) ;
|
||||
break ;
|
||||
case CRV_ARC :
|
||||
LineArcCalculate( *m_pCurve[0], *m_pCurve[1]) ;
|
||||
LineArcCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
case CRV_COMPO :
|
||||
LineCrvCompoCalculate( *m_pCurve[0], *m_pCurve[1]) ;
|
||||
LineCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
case CRV_ARC :
|
||||
switch ( m_pCurve[1]->GetType()) {
|
||||
switch ( pCalcCrv[1]->GetType()) {
|
||||
case CRV_LINE :
|
||||
ArcLineCalculate( *m_pCurve[0], *m_pCurve[1]) ;
|
||||
ArcLineCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
case CRV_ARC :
|
||||
ArcArcCalculate( *m_pCurve[0], *m_pCurve[1]) ;
|
||||
ArcArcCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
case CRV_COMPO :
|
||||
ArcCrvCompoCalculate( *m_pCurve[0], *m_pCurve[1]) ;
|
||||
ArcCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
case CRV_COMPO :
|
||||
switch ( m_pCurve[1]->GetType()) {
|
||||
switch ( pCalcCrv[1]->GetType()) {
|
||||
case CRV_LINE :
|
||||
CrvCompoLineCalculate( *m_pCurve[0], *m_pCurve[1]) ;
|
||||
CrvCompoLineCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
case CRV_ARC :
|
||||
CrvCompoArcCalculate( *m_pCurve[0], *m_pCurve[1]) ;
|
||||
CrvCompoArcCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
case CRV_COMPO :
|
||||
CrvCompoCrvCompoCalculate( *m_pCurve[0], *m_pCurve[1]) ;
|
||||
CrvCompoCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
// per curve approssimate, sistemo...
|
||||
AdjustIntersParams( ( pCalcCrv[0] != m_pCurve[0]), ( pCalcCrv[1] != m_pCurve[1])) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -233,6 +240,35 @@ IntersCurveCurve::CrvCompoCrvCompoCalculate( const ICurve& CurveA, const ICurve&
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurveCurve::AdjustIntersParams( bool bAdjCrvA, bool bAdjCrvB)
|
||||
{
|
||||
// se non ci sono intersezioni, non va fatto alcunché
|
||||
if ( m_Info.size() == 0)
|
||||
return true ;
|
||||
// se le curve originali non sono state approssimate, non va fatto alcunché
|
||||
if ( ! bAdjCrvA && ! bAdjCrvB)
|
||||
return true ;
|
||||
// procedo ad aggiustare
|
||||
for ( auto& aInfo : m_Info) {
|
||||
// se curve originali approssimate, devo ricalcolare i parametri dei punti di intersezione
|
||||
if ( bAdjCrvA) {
|
||||
if ( ! m_pCurve[0]->GetParamAtPoint( aInfo.IciA[0].ptI, aInfo.IciA[0].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( aInfo.bOverlap && ! m_pCurve[0]->GetParamAtPoint( aInfo.IciA[1].ptI, aInfo.IciA[1].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
}
|
||||
if ( bAdjCrvB) {
|
||||
if ( ! m_pCurve[1]->GetParamAtPoint( aInfo.IciB[0].ptI, aInfo.IciB[0].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( aInfo.bOverlap && ! m_pCurve[1]->GetParamAtPoint( aInfo.IciB[1].ptI, aInfo.IciB[1].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurveCurve::GetOverlaps( void)
|
||||
@@ -254,19 +290,6 @@ IntersCurveCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
|
||||
if ( nInd < 0 || nInd >= m_nNumInters)
|
||||
return false ;
|
||||
aInfo = m_Info[nInd] ;
|
||||
// se curve originali approssimate, devo ricalcolare i parametri dei punti di intersezione
|
||||
if ( m_pCurve[0] != m_pOriCrv[0]) {
|
||||
if ( ! m_pOriCrv[0]->GetParamAtPoint( aInfo.IciA[0].ptI, aInfo.IciA[0].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( aInfo.bOverlap && ! m_pOriCrv[0]->GetParamAtPoint( aInfo.IciA[1].ptI, aInfo.IciA[1].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
}
|
||||
if ( m_pCurve[1] != m_pOriCrv[1]) {
|
||||
if ( ! m_pOriCrv[1]->GetParamAtPoint( aInfo.IciB[0].ptI, aInfo.IciB[0].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( aInfo.bOverlap && ! m_pOriCrv[1]->GetParamAtPoint( aInfo.IciB[1].ptI, aInfo.IciB[1].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ void
|
||||
Intervals::Reset( void)
|
||||
{
|
||||
m_lInts.clear() ;
|
||||
m_Iter = m_lInts.end() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -139,6 +140,40 @@ Intervals::Remove( double dMin, double dMax)
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
Intervals::Union( const Intervals& Other)
|
||||
{
|
||||
// aggiungo tutti gli intervalli dell'altro
|
||||
for ( auto& Interv : Other.m_lInts)
|
||||
Add( Interv.first, Interv.second) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
Intervals::Intersection( const Intervals& Other)
|
||||
{
|
||||
// se l'insieme è vuoto non devo fare alcunché
|
||||
if ( m_lInts.empty())
|
||||
return ;
|
||||
// Insieme di intervalli ausiliario ampio come il corrente
|
||||
Intervals Aux ;
|
||||
Aux.Set( m_lInts.front().first, m_lInts.back().second) ;
|
||||
// Sottraggo Other da Aux
|
||||
Aux.Difference( Other) ;
|
||||
// Sottraggo Aux dal corrente
|
||||
Difference( Aux) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
Intervals::Difference( const Intervals& Other)
|
||||
{
|
||||
// sottraggo tutti gli intervalli dell'altro
|
||||
for ( auto& Interv : Other.m_lInts)
|
||||
Remove( Interv.first, Interv.second) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Intervals::GetMinMax( double& dMin, double& dMax)
|
||||
|
||||
+91
-37
@@ -19,6 +19,7 @@
|
||||
#include "IntersCrvCompoCrvCompo.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -29,34 +30,48 @@ SelfIntersCurve::SelfIntersCurve( const ICurve& Curve)
|
||||
|
||||
// inizializzazioni
|
||||
m_bOverlaps = false ;
|
||||
m_nNumInters = 0 ;
|
||||
m_pOriCrv = &Curve ;
|
||||
m_pCurve = nullptr ;
|
||||
m_nIntersCount = 0 ;
|
||||
m_pCurve = &Curve ;
|
||||
|
||||
// verifico che la curva sia definita
|
||||
if ( &Curve == nullptr || ! Curve.IsValid())
|
||||
return ;
|
||||
|
||||
// puntatore alla curva usata nei calcoli (originale o temporanea)
|
||||
const ICurve* pCalcCrv ;
|
||||
// eventuale approssimazione temporanea della curva
|
||||
PtrOwner<ICurve> pTmpCrv ;
|
||||
// eventuale parametrizzazione della approssimazione temporanea
|
||||
DBLVECTOR vTmpPar ;
|
||||
|
||||
// se curva è arco da approssimare oppure è curva di Bezier
|
||||
if ( ( m_pOriCrv->GetType() == CRV_ARC && IsArcToApprox( *m_pOriCrv)) ||
|
||||
m_pOriCrv->GetType() == CRV_BEZ) {
|
||||
if ( ( m_pCurve->GetType() == CRV_ARC && IsArcToApprox( *m_pCurve)) ||
|
||||
m_pCurve->GetType() == CRV_BEZ) {
|
||||
// approssimo con rette
|
||||
PolyLine PL ;
|
||||
if ( ! m_pOriCrv->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
if ( ! m_pCurve->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
return ;
|
||||
m_pTmpCrv.Set( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( m_pTmpCrv))
|
||||
pTmpCrv.Set( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pTmpCrv))
|
||||
return ;
|
||||
if ( ! GetBasicCurveComposite( Get( m_pTmpCrv))->FromPolyLine( PL))
|
||||
if ( ! GetBasicCurveComposite( Get( pTmpCrv))->FromPolyLine( PL))
|
||||
return ;
|
||||
m_pCurve = Get( m_pTmpCrv) ;
|
||||
pCalcCrv = Get( pTmpCrv) ;
|
||||
// salvo la parametrizzazione della approssimazione temporanea
|
||||
vTmpPar.reserve( PL.GetPointNbr()) ;
|
||||
double dPar ;
|
||||
bool bFound = PL.GetFirstU( dPar) ;
|
||||
while ( bFound) {
|
||||
vTmpPar.push_back( dPar) ;
|
||||
bFound = PL.GetNextU( dPar) ;
|
||||
}
|
||||
}
|
||||
// altrimenti uso la curva originale
|
||||
else
|
||||
m_pCurve = m_pOriCrv ;
|
||||
pCalcCrv = m_pCurve ;
|
||||
|
||||
// chiamo calcolatore opportuno
|
||||
switch ( m_pCurve->GetType()) {
|
||||
switch ( pCalcCrv->GetType()) {
|
||||
case CRV_LINE :
|
||||
// un segmento non può autointersecarsi (non considero auto-intersezione un segmento perpendicolare a XY)
|
||||
break ;
|
||||
@@ -64,16 +79,18 @@ SelfIntersCurve::SelfIntersCurve( const ICurve& Curve)
|
||||
// un arco nel piano XY con angolo al centro non superiore al giro non può autointersecarsi
|
||||
break ;
|
||||
case CRV_COMPO : {
|
||||
IntersCrvCompoCrvCompo intCcCc( *GetCurveComposite( &Curve), *GetCurveComposite( &Curve)) ;
|
||||
IntersCrvCompoCrvCompo intCcCc( *GetCurveComposite( pCalcCrv), *GetCurveComposite( pCalcCrv)) ;
|
||||
if ( intCcCc.m_nNumInters > 0) {
|
||||
m_bOverlaps = intCcCc.m_bOverlaps ;
|
||||
m_nNumInters = intCcCc.m_nNumInters ;
|
||||
for ( int i = 0 ; i < m_nNumInters ; ++ i)
|
||||
m_nIntersCount = intCcCc.m_nNumInters ;
|
||||
for ( int i = 0 ; i < m_nIntersCount ; ++ i)
|
||||
m_Info.push_back( intCcCc.m_Info[i]) ;
|
||||
}
|
||||
}
|
||||
break ;
|
||||
}
|
||||
// per curva approssimata, sistemo...
|
||||
AdjustIntersParams( ( pCalcCrv != m_pCurve), pCalcCrv, vTmpPar) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -89,6 +106,54 @@ SelfIntersCurve::IsArcToApprox( const ICurve& Curve)
|
||||
fabs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SelfIntersCurve::GetCurveParamFromApproxParam( double& dU, const ICurve* pCalcCrv, const DBLVECTOR& vCalcPar)
|
||||
{
|
||||
int nInd = int( dU) ;
|
||||
double dFraz = dU - nInd ;
|
||||
if ( nInd >= 0 && nInd < int( vCalcPar.size()) - 1) {
|
||||
// parametrizzazione da vettore dei parametri, uniforme in ogni intervallino
|
||||
dU = vCalcPar[nInd] + dFraz * ( vCalcPar[nInd+1] - vCalcPar[nInd]) ;
|
||||
}
|
||||
else {
|
||||
// domini parametrici delle due curve
|
||||
double dCalcS, dCalcE ;
|
||||
pCalcCrv->GetDomain( dCalcS, dCalcE) ;
|
||||
double dCrvS, dCrvE ;
|
||||
m_pCurve->GetDomain( dCrvS, dCrvE) ;
|
||||
// considero una parametrizzazione uniforme sull'intero dominio
|
||||
dU = dCrvS + ( dU - dCalcS) * ( dCrvE - dCrvS) / ( dCalcE - dCalcS) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SelfIntersCurve::AdjustIntersParams( bool bAdjCrv, const ICurve* pCalcCrv, const DBLVECTOR& vCalcPar)
|
||||
{
|
||||
// se la curva originale non è stata approssimata o non ci sono auto-intersezioni, non va fatto alcunché
|
||||
if ( ! bAdjCrv || m_Info.size() == 0)
|
||||
return true ;
|
||||
// procedo ad aggiustare
|
||||
for ( auto& aInfo : m_Info) {
|
||||
// devo ricalcolare i parametri dei punti di intersezione
|
||||
GetCurveParamFromApproxParam( aInfo.IciA[0].dU, pCalcCrv, vCalcPar) ;
|
||||
ImproveCurveParamAtPoint( aInfo.IciA[0].dU, aInfo.IciA[0].ptI, m_pCurve) ;
|
||||
if ( aInfo.bOverlap) {
|
||||
GetCurveParamFromApproxParam( aInfo.IciA[1].dU, pCalcCrv, vCalcPar) ;
|
||||
ImproveCurveParamAtPoint( aInfo.IciA[1].dU, aInfo.IciA[1].ptI, m_pCurve) ;
|
||||
}
|
||||
GetCurveParamFromApproxParam( aInfo.IciB[0].dU, pCalcCrv, vCalcPar) ;
|
||||
ImproveCurveParamAtPoint( aInfo.IciB[0].dU, aInfo.IciB[0].ptI, m_pCurve) ;
|
||||
if ( aInfo.bOverlap) {
|
||||
GetCurveParamFromApproxParam( aInfo.IciB[1].dU, pCalcCrv, vCalcPar) ;
|
||||
ImproveCurveParamAtPoint( aInfo.IciB[1].dU, aInfo.IciB[1].ptI, m_pCurve) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SelfIntersCurve::GetOverlaps( void)
|
||||
@@ -98,49 +163,38 @@ SelfIntersCurve::GetOverlaps( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SelfIntersCurve::GetNumInters( void)
|
||||
SelfIntersCurve::GetIntersCount( void)
|
||||
{
|
||||
return m_nNumInters ;
|
||||
return m_nIntersCount ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SelfIntersCurve::GetNumCrossInters( void)
|
||||
SelfIntersCurve::GetCrossIntersCount( void)
|
||||
{
|
||||
int nNumCrossInters = 0 ;
|
||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||
int nCrossIntersCount = 0 ;
|
||||
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
||||
// se con sovrapposizione
|
||||
if ( m_Info[i].bOverlap) {
|
||||
if ( m_Info[i].IciA[0].nPrevTy != m_Info[i].IciA[1].nNextTy)
|
||||
++ nNumCrossInters ;
|
||||
++ nCrossIntersCount ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( m_Info[i].IciA[0].nPrevTy != m_Info[i].IciA[0].nNextTy)
|
||||
++ nNumCrossInters ;
|
||||
++ nCrossIntersCount ;
|
||||
}
|
||||
}
|
||||
return nNumCrossInters ;
|
||||
return nCrossIntersCount ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SelfIntersCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
|
||||
{
|
||||
if ( nInd < 0 || nInd >= m_nNumInters)
|
||||
if ( nInd < 0 || nInd >= m_nIntersCount)
|
||||
return false ;
|
||||
aInfo = m_Info[nInd] ;
|
||||
// se curva originale approssimata, devo ricalcolare i parametri dei punti di intersezione
|
||||
if ( m_pCurve != m_pOriCrv) {
|
||||
if ( ! m_pOriCrv->GetParamAtPoint( aInfo.IciA[0].ptI, aInfo.IciA[0].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( aInfo.bOverlap && ! m_pOriCrv->GetParamAtPoint( aInfo.IciA[1].ptI, aInfo.IciA[1].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( ! m_pOriCrv->GetParamAtPoint( aInfo.IciB[0].ptI, aInfo.IciB[0].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( aInfo.bOverlap && ! m_pOriCrv->GetParamAtPoint( aInfo.IciB[1].ptI, aInfo.IciB[1].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -148,13 +202,13 @@ SelfIntersCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
|
||||
bool
|
||||
SelfIntersCurve::GetIntersPointNearTo( const Point3d& ptNear, Point3d& ptI)
|
||||
{
|
||||
if ( m_nNumInters == 0)
|
||||
if ( m_nIntersCount == 0)
|
||||
return false ;
|
||||
|
||||
// ricerca del punto più vicino tra le intersezioni singole
|
||||
bool bFound = false ;
|
||||
double dMinSqDist = INFINITO * INFINITO ;
|
||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
||||
// se è un'intersezione singola
|
||||
if ( ! m_Info[i].bOverlap) {
|
||||
// faccio la verifica sul punto
|
||||
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2015
|
||||
//----------------------------------------------------------------------------
|
||||
// File : StmFromCurves.cpp Data : 01.02.15 Versione : 1.6b1
|
||||
// Contenuto : Implementazione di funzioni per creazione di superfici Stm
|
||||
// a partire da curve, con diversi metodi.
|
||||
//
|
||||
//
|
||||
// Modifiche : 01.02.15 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveArc.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionRectangle( double dWidth, double dLen)
|
||||
{
|
||||
// le dimensioni devono essere significative
|
||||
if ( dWidth < EPS_SMALL || dLen < EPS_SMALL)
|
||||
return nullptr ;
|
||||
// creo il contorno
|
||||
PolyLine PL ;
|
||||
PL.AddUPoint( 0, ORIG) ;
|
||||
PL.AddUPoint( 1, Point3d( dWidth, 0, 0)) ;
|
||||
PL.AddUPoint( 2, Point3d( dWidth, dLen, 0)) ;
|
||||
PL.AddUPoint( 3, Point3d( 0, dLen, 0)) ;
|
||||
PL.AddUPoint( 4, ORIG) ;
|
||||
PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pCC) || ! pCC->FromPolyLine( PL))
|
||||
return nullptr ;
|
||||
// creo il rettangolo
|
||||
PtrOwner<ISurfFlatRegion> pSfr( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( Release( pCC)))
|
||||
return nullptr ;
|
||||
else
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionStadium( double dWidth, double dLen)
|
||||
{
|
||||
// le dimensioni devono essere significative
|
||||
if ( dWidth < EPS_SMALL || dLen < EPS_SMALL)
|
||||
return nullptr ;
|
||||
// se dimensioni praticamente uguali, è un disco
|
||||
if ( fabs( dWidth - dLen) < 10 * EPS_SMALL)
|
||||
return GetSurfFlatRegionDisk( ( dWidth + dLen) / 4) ;
|
||||
// creo il contorno
|
||||
PolyArc PA ;
|
||||
if ( dWidth > dLen) {
|
||||
double dRad = dLen / 2 ;
|
||||
PA.AddUPoint( 0, Point3d( dRad, 0, 0), 0) ;
|
||||
PA.AddUPoint( 1, Point3d( dWidth - dRad, 0, 0), 1) ;
|
||||
PA.AddUPoint( 2, Point3d( dWidth - dRad, dLen, 0), 0) ;
|
||||
PA.AddUPoint( 3, Point3d( dRad, dLen, 0), 1) ;
|
||||
PA.AddUPoint( 4, Point3d( dRad, 0, 0), 0) ;
|
||||
}
|
||||
else {
|
||||
double dRad = dWidth / 2 ;
|
||||
PA.AddUPoint( 0, Point3d( dWidth, dRad, 0), 0) ;
|
||||
PA.AddUPoint( 1, Point3d( dWidth, dLen - dRad, 0), 1) ;
|
||||
PA.AddUPoint( 2, Point3d( 0, dLen - dRad, 0), 0) ;
|
||||
PA.AddUPoint( 3, Point3d( 0, dRad, 0), 1) ;
|
||||
PA.AddUPoint( 4, Point3d( dWidth, dRad, 0), 0) ;
|
||||
}
|
||||
PtrOwner<CurveComposite> pCC( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pCC) || ! pCC->FromPolyArc( PA))
|
||||
return nullptr ;
|
||||
// creo il rettangolo
|
||||
PtrOwner<ISurfFlatRegion> pSfr( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( Release( pCC)))
|
||||
return nullptr ;
|
||||
else
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionDisk( double dRadius)
|
||||
{
|
||||
// le dimensioni devono essere significative
|
||||
if ( dRadius < EPS_SMALL)
|
||||
return nullptr ;
|
||||
// creo la circonferenza di riferimento
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pArc))
|
||||
return nullptr ;
|
||||
pArc->Set( ORIG, Z_AX, dRadius, X_AX, ANG_FULL, 0) ;
|
||||
// creo il disco
|
||||
PtrOwner<ISurfFlatRegion> pSfr( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( Release( pArc)))
|
||||
return nullptr ;
|
||||
else
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Classe SurfFlatRegionByContours
|
||||
//-------------------------------------------------------------------------------
|
||||
SurfFlatRegionByContours::~SurfFlatRegionByContours(void)
|
||||
{
|
||||
// cancello eventuali curve rimaste
|
||||
for ( auto& pCrv : m_vpCrv) {
|
||||
if ( pCrv != nullptr)
|
||||
delete pCrv ;
|
||||
pCrv = nullptr ;
|
||||
}
|
||||
m_vpCrv.clear() ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegionByContours::AddCurve( ICurve* pCrv)
|
||||
{
|
||||
// acquisisco la curva
|
||||
PtrOwner<ICurve> pMyCrv( pCrv) ;
|
||||
if ( IsNull( pMyCrv) || ! pMyCrv->IsValid())
|
||||
return false ;
|
||||
// verifico sia chiusa
|
||||
if ( ! pMyCrv->IsClosed())
|
||||
return false ;
|
||||
// la inserisco nel vettore delle curve
|
||||
m_vpCrv.push_back( Release( pMyCrv)) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegionByContours::Prepare( void)
|
||||
{
|
||||
// calcolo piano medio e area delle curve
|
||||
m_vArea.reserve( m_vpCrv.size()) ;
|
||||
Vector3d vtN0 ;
|
||||
for ( int i = 0 ; i < int( m_vpCrv.size()) ; ++ i) {
|
||||
// calcolo piano medio e area
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! m_vpCrv[i]->GetArea( plPlane, dArea))
|
||||
return false ;
|
||||
// imposto la normale del primo contorno come riferimento
|
||||
if ( i == 0)
|
||||
vtN0 = plPlane.vtN ;
|
||||
// verifico che le normali siano molto vicine
|
||||
if ( ! AreSameOrOppositeVectorApprox( plPlane.vtN, vtN0))
|
||||
return false ;
|
||||
// assegno il segno all'area secondo il verso della normale
|
||||
if ( ( plPlane.vtN * vtN0) > 0)
|
||||
m_vArea.emplace_back( i, dArea) ;
|
||||
else
|
||||
m_vArea.emplace_back( i, - dArea) ;
|
||||
}
|
||||
// ordino in senso decrescente sull'area
|
||||
sort( m_vArea.begin(), m_vArea.end(),
|
||||
[]( const INDAREA& a, const INDAREA&b) { return fabs( a.second) > fabs( b.second) ; }) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
SurfFlatRegionByContours::GetSurf( void)
|
||||
{
|
||||
// se è la prima superficie, devo preparare
|
||||
if ( m_bFirst) {
|
||||
if ( ! Prepare())
|
||||
return nullptr ;
|
||||
m_bFirst = false ;
|
||||
}
|
||||
// altrimenti, se ammessa una sola superficie errore
|
||||
else if ( ! m_bAllowedMore) {
|
||||
return nullptr ;
|
||||
}
|
||||
// creo la superficie
|
||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr))
|
||||
return nullptr ;
|
||||
// aggiungo le diverse curve
|
||||
bool bFirstCrv ;
|
||||
do {
|
||||
bFirstCrv = true ;
|
||||
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i) {
|
||||
// recupero indice di percorso e verifico sia valido
|
||||
int j = m_vArea[i].first ;
|
||||
if ( j < 0)
|
||||
continue ;
|
||||
// la prima deve essere il loop esterno
|
||||
if ( bFirstCrv) {
|
||||
// ne faccio una copia
|
||||
PtrOwner<ICurve> pCrv( m_vpCrv[j]->Clone()) ;
|
||||
if ( IsNull( pCrv)) {
|
||||
m_vArea[i].first = - 1 ;
|
||||
continue ;
|
||||
}
|
||||
// provo a inserirla
|
||||
if ( pSfr->AddExtLoop( Release( pCrv))) {
|
||||
bFirstCrv = false ;
|
||||
delete m_vpCrv[j] ;
|
||||
m_vpCrv[j] = nullptr ;
|
||||
m_vArea[i].first = - 1 ;
|
||||
}
|
||||
}
|
||||
// gli altri sono loop interni
|
||||
else {
|
||||
// ne faccio una copia
|
||||
PtrOwner<ICurve> pCrv( m_vpCrv[j]->Clone()) ;
|
||||
if ( IsNull( pCrv)) {
|
||||
m_vArea[i].first = - 1 ;
|
||||
continue ;
|
||||
}
|
||||
// provo a inserirla
|
||||
if ( pSfr->AddIntLoop( Release( pCrv))) {
|
||||
delete m_vpCrv[j] ;
|
||||
m_vpCrv[j] = nullptr ;
|
||||
m_vArea[i].first = - 1 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ( m_bAllowedMultiChunk && ! bFirstCrv) ;
|
||||
// se non valida, errore
|
||||
if ( ! pSfr->IsValid())
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegionByContours::AllCurvesUsed( void)
|
||||
{
|
||||
// verifico se cono rimaste delle curve
|
||||
for ( auto& pCrv : m_vpCrv) {
|
||||
if ( pCrv != nullptr)
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
+6
-6
@@ -21,7 +21,7 @@
|
||||
using namespace std ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
static bool CalcRegionPolyLines( const ICURVEPVECTOR& vpCurve, double dLinTol,
|
||||
static bool CalcRegionPolyLines( const CICURVEPVECTOR& vpCurve, double dLinTol,
|
||||
POLYLINEVECTOR& vPL, Vector3d& vtN) ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
@@ -47,7 +47,7 @@ GetSurfTriMeshByFlatContour( const ICurve* pCurve, double dLinTol)
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshByRegion( const ICURVEPVECTOR& vpCurve, double dLinTol)
|
||||
GetSurfTriMeshByRegion( const CICURVEPVECTOR& vpCurve, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( &vpCurve == nullptr || vpCurve.empty())
|
||||
@@ -126,7 +126,7 @@ GetSurfTriMeshByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshByRegionExtrusion( const ICURVEPVECTOR& vpCurve, const Vector3d& vtExtr, double dLinTol)
|
||||
GetSurfTriMeshByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d& vtExtr, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( &vpCurve == nullptr || vpCurve.empty() || &vtExtr == nullptr)
|
||||
@@ -330,7 +330,7 @@ GetSurfTriMeshRuled( const ICurve* pCurve1, const ICurve* pCurve2, double dLinTo
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool
|
||||
CalcRegionPolyLines( const ICURVEPVECTOR& vpCurve, double dLinTol,
|
||||
CalcRegionPolyLines( const CICURVEPVECTOR& vpCurve, double dLinTol,
|
||||
POLYLINEVECTOR& vPL, Vector3d& vtN)
|
||||
{
|
||||
// calcolo le polilinee che approssimano le curve
|
||||
@@ -341,8 +341,8 @@ CalcRegionPolyLines( const ICURVEPVECTOR& vpCurve, double dLinTol,
|
||||
return nullptr ;
|
||||
}
|
||||
// ne calcolo l'area e genero un ordine in senso decrescente
|
||||
typedef std::pair<int,double> INDAREA ; // coppia indice, area
|
||||
typedef std::vector<INDAREA> INDAREAVECTOR ; // vettore di coppie indice, area
|
||||
typedef pair<int,double> INDAREA ; // coppia indice, area
|
||||
typedef vector<INDAREA> INDAREAVECTOR ; // vettore di coppie indice, area
|
||||
INDAREAVECTOR vArea ;
|
||||
vArea.reserve( vPLtmp.size()) ;
|
||||
Vector3d vtN0 ;
|
||||
|
||||
+369
-213
@@ -31,7 +31,7 @@ GEOOBJ_REGISTER( SRF_FLATRGN, NGE_S_FRG, SurfFlatRegion) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
SurfFlatRegion::SurfFlatRegion( void)
|
||||
: m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_pExtLoop( nullptr), m_nTempProp(), m_Iter( m_vpIntLoop.end())
|
||||
: m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_nTempProp()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -45,32 +45,26 @@ SurfFlatRegion::~SurfFlatRegion( void)
|
||||
bool
|
||||
SurfFlatRegion::Clear( void)
|
||||
{
|
||||
if ( m_pSTM != nullptr)
|
||||
delete( m_pSTM) ;
|
||||
m_pSTM = nullptr ;
|
||||
m_nStatus = TO_VERIFY ;
|
||||
m_frF.Reset() ;
|
||||
|
||||
// ciclo di pulizia
|
||||
if ( m_pExtLoop != nullptr)
|
||||
delete( m_pExtLoop) ;
|
||||
m_pExtLoop = nullptr ;
|
||||
for ( auto Iter = m_vpIntLoop.begin() ; Iter != m_vpIntLoop.end() ; ++Iter)
|
||||
delete (*Iter) ;
|
||||
m_vpIntLoop.clear() ;
|
||||
// pulizia dei loop
|
||||
for ( auto& pLoop : m_vpLoop)
|
||||
delete pLoop ;
|
||||
m_vpLoop.clear() ;
|
||||
|
||||
m_nTempProp = 0 ;
|
||||
m_Iter = m_vpIntLoop.end() ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
ResetAuxSurf() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::SetExtLoop( const ICurve& cCrv)
|
||||
SurfFlatRegion::AddExtLoop( const ICurve& cCrv)
|
||||
{
|
||||
// verifico validità curva
|
||||
if ( &cCrv == nullptr)
|
||||
@@ -80,15 +74,13 @@ SurfFlatRegion::SetExtLoop( const ICurve& cCrv)
|
||||
if ( pCrv == nullptr)
|
||||
return false ;
|
||||
// procedo
|
||||
return SetExtLoop( pCrv) ;
|
||||
return AddExtLoop( pCrv) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::SetExtLoop( ICurve* pCrv)
|
||||
SurfFlatRegion::AddExtLoop( ICurve* pCrv)
|
||||
{
|
||||
// resetto tutto
|
||||
Clear() ;
|
||||
// acquisisco la curva
|
||||
PtrOwner<ICurve> pMyCrv( pCrv) ;
|
||||
if ( IsNull( pMyCrv))
|
||||
@@ -97,28 +89,71 @@ SurfFlatRegion::SetExtLoop( ICurve* pCrv)
|
||||
if ( ! pMyCrv->IsClosed())
|
||||
return false ;
|
||||
// verifico sia piana
|
||||
double dArea ;
|
||||
Plane3d plPlane ;
|
||||
if ( ! pMyCrv->IsFlat( plPlane))
|
||||
return false ;
|
||||
// assegno il riferimento intrinseco
|
||||
if ( ! m_frF.Set( ORIG + plPlane.vtN * plPlane.dDist, plPlane.vtN))
|
||||
if ( ! pMyCrv->GetArea( plPlane, dArea))
|
||||
return false ;
|
||||
// se sto costruendo il primo chunk
|
||||
if ( m_vExtInd.size() == 0) {
|
||||
// assegno il riferimento intrinseco
|
||||
if ( ! m_frF.Set( ORIG + plPlane.vtN * plPlane.dDist, plPlane.vtN))
|
||||
return false ;
|
||||
// sistemo il senso di rotazione (deve essere CCW -> area > 0)
|
||||
if ( dArea < 0)
|
||||
pMyCrv->Invert() ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
// verifico che il piano della curva coincida con quello XY intrinseco
|
||||
plPlane.ToLoc( m_frF) ;
|
||||
if ( ! ( plPlane.vtN.IsZplus() || plPlane.vtN.IsZminus()) || fabs( plPlane.dDist) > EPS_SMALL)
|
||||
return false ;
|
||||
// sistemo il senso di rotazione (deve essere CCW -> area > 0)
|
||||
if ( ( plPlane.vtN.IsZplus() && dArea < 0) ||
|
||||
( plPlane.vtN.IsZminus() && dArea > 0))
|
||||
pMyCrv->Invert() ;
|
||||
}
|
||||
// porto la curva nel riferimento intrinseco
|
||||
if ( ! pMyCrv->ToLoc( m_frF))
|
||||
return false ;
|
||||
// verifico non abbia auto-intersezioni
|
||||
SelfIntersCurve sInt( *pMyCrv) ;
|
||||
if ( sInt.GetNumInters() > 0)
|
||||
if ( sInt.GetIntersCount() > 0)
|
||||
return false ;
|
||||
// sistemo il senso di rotazione (deve essere CCW -> area > 0)
|
||||
double dArea ;
|
||||
if ( ! pMyCrv->GetAreaXY( dArea) || fabs( dArea) < 100 * EPS_SMALL * EPS_SMALL)
|
||||
// verifico che sia esterna alle curve esterne degli altri chunk
|
||||
bool bOk = true ;
|
||||
CRVCVECTOR ccClass ;
|
||||
for ( auto i : m_vExtInd) {
|
||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
||||
if ( ccInt.GetNumInters() > 0 ||
|
||||
! ccInt.GetCurveClassification( 0, ccClass) ||
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_OUT) {
|
||||
bOk = false ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
// oppure esterna ad un loop interno degli altri chunk
|
||||
for ( int i = 0 ; i < int( m_vpLoop.size()) ; ++ i) {
|
||||
// se loop esterno, salto
|
||||
if ( binary_search( m_vExtInd.begin(), m_vExtInd.end(), i))
|
||||
continue ;
|
||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
||||
if ( ccInt.GetNumInters() == 0 &&
|
||||
ccInt.GetCurveClassification( 0, ccClass) &&
|
||||
! ccClass.empty() && ccClass[0].nClass == CRVC_OUT) {
|
||||
bOk = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( ! bOk)
|
||||
return false ;
|
||||
if ( dArea < 0)
|
||||
pMyCrv->Invert() ;
|
||||
// assegno la curva al loop esterno
|
||||
m_pExtLoop = Release( pMyCrv) ;
|
||||
// assegno la curva come loop esterno
|
||||
m_vpLoop.push_back( Release( pMyCrv)) ;
|
||||
m_vExtInd.push_back( int( m_vpLoop.size()) - 1) ;
|
||||
m_nStatus = OK ;
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -143,10 +178,10 @@ SurfFlatRegion::AddIntLoop( ICurve* pCrv)
|
||||
{
|
||||
// acquisisco la curva
|
||||
PtrOwner<ICurve> pMyCrv( pCrv) ;
|
||||
if ( IsNull( pMyCrv))
|
||||
if ( IsNull( pMyCrv) || ! pMyCrv->IsValid())
|
||||
return false ;
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_pExtLoop == nullptr)
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// verifico sia chiusa
|
||||
if ( ! pMyCrv->IsClosed())
|
||||
@@ -155,36 +190,33 @@ SurfFlatRegion::AddIntLoop( ICurve* pCrv)
|
||||
if ( ! pMyCrv->ToLoc( m_frF))
|
||||
return false ;
|
||||
// verifico sia piana e il piano coincida con quello XY intrinseco
|
||||
double dArea ;
|
||||
Plane3d plPlane ;
|
||||
if ( ! pMyCrv->IsFlat( plPlane))
|
||||
if ( ! pMyCrv->GetArea( plPlane, dArea))
|
||||
return false ;
|
||||
if ( ! plPlane.vtN.IsZplus() && ! plPlane.vtN.IsZminus() && fabs( plPlane.dDist) > EPS_SMALL)
|
||||
if ( ! ( plPlane.vtN.IsZplus() || plPlane.vtN.IsZminus()) || fabs( plPlane.dDist) > EPS_SMALL)
|
||||
return false ;
|
||||
// sistemo il senso di rotazione (deve essere CW -> se N==Z+ area < 0, se N==Z- area>0)
|
||||
if ( ( plPlane.vtN.IsZplus() && dArea > 0) || ( plPlane.vtN.IsZminus() && dArea < 0))
|
||||
pMyCrv->Invert() ;
|
||||
// verifico non abbia auto-intersezioni
|
||||
SelfIntersCurve sInt( *pMyCrv) ;
|
||||
if ( sInt.GetNumInters() > 0)
|
||||
if ( sInt.GetIntersCount() > 0)
|
||||
return false ;
|
||||
// verifico non abbia intersezioni e sia interna al loop esterno
|
||||
IntersCurveCurve ccInt( *pMyCrv, *m_pExtLoop) ;
|
||||
// verifico non abbia intersezioni e non sia esterna ai loop già definiti del medesimo chunk
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ccInt.GetNumInters() > 0 ||
|
||||
! ccInt.GetCurveClassification( 0, ccClass) ||
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||
return false ;
|
||||
// verifico non abbia intersezioni con eventuali altri loop interni
|
||||
for ( auto& pIntLoop : m_vpIntLoop) {
|
||||
IntersCurveCurve ccInt( *pMyCrv, *pIntLoop) ;
|
||||
if ( ccInt.GetNumInters() > 0)
|
||||
for ( int i = m_vExtInd.back() ; i < int( m_vpLoop.size()) ; ++ i) {
|
||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
||||
if ( ccInt.GetNumInters() > 0 ||
|
||||
! ccInt.GetCurveClassification( 0, ccClass) ||
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||
return false ;
|
||||
}
|
||||
// sistemo il senso di rotazione (deve essere CW -> area < 0)
|
||||
double dArea ;
|
||||
if ( ! pMyCrv->GetAreaXY( dArea) || fabs( dArea) < 100 * EPS_SMALL * EPS_SMALL)
|
||||
return false ;
|
||||
if ( dArea > 0)
|
||||
pMyCrv->Invert() ;
|
||||
// aggiungo la curva all'elenco dei loop interni
|
||||
m_vpIntLoop.push_back( Release( pMyCrv)) ;
|
||||
// aggiungo la curva all'elenco dei loop
|
||||
m_vpLoop.push_back( Release( pMyCrv)) ;
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
m_OGrMgr.Reset() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -224,17 +256,16 @@ SurfFlatRegion::CopyFrom( const SurfFlatRegion& sfrSrc)
|
||||
if ( sfrSrc.m_pSTM != nullptr)
|
||||
m_pSTM = sfrSrc.m_pSTM->Clone() ;
|
||||
m_frF = sfrSrc.m_frF ;
|
||||
if ( sfrSrc.m_pExtLoop != nullptr)
|
||||
m_pExtLoop = sfrSrc.m_pExtLoop->Clone() ;
|
||||
for ( auto& pIntLoop : sfrSrc.m_vpIntLoop) {
|
||||
ICurve* pCrv = pIntLoop->Clone() ;
|
||||
for ( auto& pLoop : sfrSrc.m_vpLoop) {
|
||||
ICurve* pCrv = pLoop->Clone() ;
|
||||
if ( pCrv == nullptr)
|
||||
return false ;
|
||||
m_vpIntLoop.push_back( pCrv) ;
|
||||
m_vpLoop.push_back( pCrv) ;
|
||||
}
|
||||
m_vExtInd = sfrSrc.m_vExtInd ;
|
||||
m_nTempProp = sfrSrc.m_nTempProp ;
|
||||
m_nStatus = sfrSrc.m_nStatus ;
|
||||
return ( m_nStatus == OK && m_pExtLoop != nullptr) ;
|
||||
return ( m_nStatus == OK && ! m_vpLoop.empty()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -268,19 +299,27 @@ SurfFlatRegion::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
||||
sOut += "VX(" + ToString( m_frF.VersX()) + ")" + szNewLine ;
|
||||
sOut += "VY(" + ToString( m_frF.VersY()) + ")" + szNewLine ;
|
||||
sOut += "VZ(" + ToString( m_frF.VersZ()) + ")" + szNewLine ;
|
||||
// loop esterno
|
||||
if ( m_pExtLoop != nullptr) {
|
||||
sOut += string( "External Loop :") + szNewLine ;
|
||||
m_pExtLoop->Dump( sOut, bMM, szNewLine) ;
|
||||
}
|
||||
else
|
||||
sOut += string( "External Loop Invalid") + szNewLine ;
|
||||
// loop interni
|
||||
sOut += "Internal Loops=" + ToString( GetIntLoopNumber()) + szNewLine ;
|
||||
int i = 0 ;
|
||||
for ( auto& pIntLoop : m_vpIntLoop) {
|
||||
sOut += "##" + ToString( ++i) + szNewLine ;
|
||||
pIntLoop->Dump( sOut, bMM, szNewLine) ;
|
||||
// ciclo sui chunk (parti connesse)
|
||||
int nChunkCount = GetChunkCount() ;
|
||||
sOut += string( "Chunks =") + ToString( nChunkCount) + szNewLine ;
|
||||
for ( int i = 0 ; i < nChunkCount ; ++ i) {
|
||||
int nLoopCount = GetLoopCount( i) ;
|
||||
// ciclo sui loop del chunk
|
||||
for ( int j = 0 ; j < nLoopCount ; ++ j) {
|
||||
int k = GetIndFromChunkLoop( i, j) ;
|
||||
// loop esterno
|
||||
if ( j == 0) {
|
||||
sOut += "Chunk # " + ToString( i) + szNewLine ;
|
||||
sOut += string( "External Loop : ") + szNewLine ;
|
||||
m_vpLoop[k]->Dump( sOut, bMM, szNewLine) ;
|
||||
sOut += "Internal Loops =" + ToString( GetLoopCount( i) - 1) + szNewLine ;
|
||||
}
|
||||
// loop interno
|
||||
else {
|
||||
sOut += "## " + ToString( j) + szNewLine ;
|
||||
m_vpLoop[k]->Dump( sOut, bMM, szNewLine) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
@@ -301,29 +340,33 @@ SurfFlatRegion::Save( NgeWriter& ngeOut) const
|
||||
if ( ! ngeOut.WriteFrame( m_frF, ";", true))
|
||||
return false ;
|
||||
// numero di loops (esterno + interni)
|
||||
if ( ! ngeOut.WriteInt( 1 + int( m_vpIntLoop.size()), nullptr, true))
|
||||
if ( ! ngeOut.WriteInt( int( m_vpLoop.size()), nullptr, true))
|
||||
return false ;
|
||||
// ciclo sui loop
|
||||
int i = 0 ;
|
||||
const ICurve* pCrv = GetMyLoop( i) ;
|
||||
while ( pCrv != nullptr) {
|
||||
for ( auto& pLoop : m_vpLoop) {
|
||||
// recupero il gestore di lettura/scrittura della curva
|
||||
const IGeoObjRW* pCSmplRW = dynamic_cast<const IGeoObjRW*>( pCrv) ;
|
||||
if ( pCSmplRW == nullptr)
|
||||
const IGeoObjRW* pLoopRW = dynamic_cast<const IGeoObjRW*>( pLoop) ;
|
||||
if ( pLoopRW == nullptr)
|
||||
return false ;
|
||||
// emetto il tipo della curva
|
||||
if ( ! ngeOut.WriteKey( pCSmplRW->GetNgeId()))
|
||||
if ( ! ngeOut.WriteKey( pLoopRW->GetNgeId()))
|
||||
return false ;
|
||||
// assegno ed emetto il nome della curva
|
||||
// assegno ed emetto il nome della curva, seguito da chunk e loop
|
||||
string sCrvName = "##" + ToString( i) ;
|
||||
if ( ! ngeOut.WriteString( sCrvName, nullptr, true))
|
||||
if ( ! ngeOut.WriteString( sCrvName, ";"))
|
||||
return false ;
|
||||
int nChunk, nLoop ;
|
||||
if ( ! GetChunkLoopFromInd( i, nChunk, nLoop))
|
||||
return false ;
|
||||
if ( ! ngeOut.WriteInt( nChunk, ",") ||
|
||||
! ngeOut.WriteInt( nLoop, ";", true))
|
||||
return false ;
|
||||
// salvo la curva
|
||||
if ( ! pCSmplRW->Save( ngeOut))
|
||||
if ( ! pLoopRW->Save( ngeOut))
|
||||
return false ;
|
||||
// passo alla successiva
|
||||
++ i ;
|
||||
pCrv = GetMyLoop( i) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
@@ -352,11 +395,14 @@ SurfFlatRegion::Load( NgeReader& ngeIn)
|
||||
IGeoObj* pGeoO = GEOOBJ_CREATE( nType) ;
|
||||
if ( pGeoO == nullptr)
|
||||
return false ;
|
||||
// recupero la linea con il nome
|
||||
// recupero la linea con il nome, chunk e loop
|
||||
string sName ;
|
||||
int j ;
|
||||
bool bOk = ngeIn.ReadString( sName, nullptr, true) &&
|
||||
bool bOk = ngeIn.ReadString( sName, ";") &&
|
||||
FromString( sName.substr(2), j) && i == j ;
|
||||
int nChunk, nLoop ;
|
||||
bOk = ngeIn.ReadInt( nChunk, ",") &&
|
||||
ngeIn.ReadInt( nLoop, ";", true) ;
|
||||
// ne leggo i dati
|
||||
IGeoObjRW* pGObjRW = dynamic_cast<IGeoObjRW*>( pGeoO) ;
|
||||
bOk = bOk && ( pGObjRW != nullptr && pGObjRW->Load( ngeIn)) ;
|
||||
@@ -365,10 +411,11 @@ SurfFlatRegion::Load( NgeReader& ngeIn)
|
||||
bOk = bOk && ( pCrv != nullptr) ;
|
||||
// aggiungo questa curva
|
||||
if ( bOk) {
|
||||
if ( i == 0)
|
||||
m_pExtLoop = pCrv ;
|
||||
else
|
||||
m_vpIntLoop.push_back( pCrv) ;
|
||||
m_vpLoop.push_back( pCrv) ;
|
||||
if ( nLoop == 0) {
|
||||
m_vExtInd.push_back( i) ;
|
||||
bOk = ( nChunk + 1 == int( m_vExtInd.size())) ;
|
||||
}
|
||||
}
|
||||
// se errore
|
||||
if ( ! bOk)
|
||||
@@ -384,10 +431,10 @@ bool
|
||||
SurfFlatRegion::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_pExtLoop == nullptr)
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// è il bounding box del loop esterno
|
||||
return m_pExtLoop->GetBBox( m_frF, b3Loc, nFlag) ;
|
||||
return m_vpLoop[0]->GetBBox( m_frF, b3Loc, nFlag) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -395,12 +442,12 @@ bool
|
||||
SurfFlatRegion::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_pExtLoop == nullptr)
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// frame composito
|
||||
Frame3d frCompo = m_frF * frRef ;
|
||||
// è il bounding box del loop esterno
|
||||
return m_pExtLoop->GetBBox( frCompo, b3Ref, nFlag) ;
|
||||
return m_vpLoop[0]->GetBBox( frCompo, b3Ref, nFlag) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -437,7 +484,7 @@ bool
|
||||
SurfFlatRegion::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ)
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_pExtLoop == nullptr)
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
@@ -455,18 +502,17 @@ SurfFlatRegion::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, dou
|
||||
|
||||
// porto i loop nel nuovo riferimento, senza modificarne la geometria in globale
|
||||
frTrasf.ToLoc( m_frF) ;
|
||||
m_pExtLoop->ToGlob( frTrasf) ;
|
||||
for ( auto& pIntLoop : m_vpIntLoop)
|
||||
pIntLoop->ToGlob( frTrasf) ;
|
||||
for ( auto& pLoop : m_vpLoop)
|
||||
pLoop->ToGlob( frTrasf) ;
|
||||
|
||||
// porto il riferimento di scalatura nel nuovo riferimento del gruppo
|
||||
Frame3d frRefLoc = frRef ;
|
||||
frRefLoc.ToLoc( m_frF) ;
|
||||
|
||||
// ciclo sui loop
|
||||
bool bOk = m_pExtLoop->Scale( frRefLoc, dCoeffX, dCoeffY, dCoeffZ) ;
|
||||
for ( auto& pIntLoop : m_vpIntLoop) {
|
||||
if ( ! pIntLoop->Scale( frRefLoc, dCoeffX, dCoeffY, dCoeffZ))
|
||||
bool bOk = true ;
|
||||
for ( auto& pLoop : m_vpLoop) {
|
||||
if ( ! pLoop->Scale( frRefLoc, dCoeffX, dCoeffY, dCoeffZ))
|
||||
bOk = false ;
|
||||
}
|
||||
|
||||
@@ -478,7 +524,7 @@ bool
|
||||
SurfFlatRegion::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_pExtLoop == nullptr)
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
@@ -490,9 +536,8 @@ SurfFlatRegion::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
|
||||
// porto i loop nel nuovo riferimento, senza modificarne la geometria in globale
|
||||
frTrasf.ToLoc( m_frF) ;
|
||||
m_pExtLoop->ToGlob( frTrasf) ;
|
||||
for ( auto& pIntLoop : m_vpIntLoop)
|
||||
pIntLoop->ToGlob( frTrasf) ;
|
||||
for ( auto& pLoop : m_vpLoop)
|
||||
pLoop->ToGlob( frTrasf) ;
|
||||
|
||||
// porto i dati del piano di mirror nel riferimento del gruppo
|
||||
Point3d ptOnLoc = ptOn ;
|
||||
@@ -501,9 +546,9 @@ SurfFlatRegion::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
vtNormLoc.ToLoc( m_frF) ;
|
||||
|
||||
// ciclo sui loop (mirror + invert)
|
||||
bool bOk = m_pExtLoop->Mirror( ptOnLoc, vtNormLoc) && m_pExtLoop->Invert() ;
|
||||
for ( auto& pIntLoop : m_vpIntLoop) {
|
||||
if ( ! pIntLoop->Mirror( ptOnLoc, vtNormLoc) || ! pIntLoop->Invert())
|
||||
bool bOk = true ;
|
||||
for ( auto& pLoop : m_vpLoop) {
|
||||
if ( ! pLoop->Mirror( ptOnLoc, vtNormLoc) || ! pLoop->Invert())
|
||||
bOk = false ;
|
||||
}
|
||||
|
||||
@@ -523,7 +568,7 @@ bool
|
||||
SurfFlatRegion::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff)
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_pExtLoop == nullptr)
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
@@ -541,9 +586,8 @@ SurfFlatRegion::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector
|
||||
|
||||
// porto i loop nel nuovo riferimento, senza modificarne la geometria in globale
|
||||
frTrasf.ToLoc( m_frF) ;
|
||||
m_pExtLoop->ToGlob( frTrasf) ;
|
||||
for ( auto& pIntLoop : m_vpIntLoop)
|
||||
pIntLoop->ToGlob( frTrasf) ;
|
||||
for ( auto& pLoop : m_vpLoop)
|
||||
pLoop->ToGlob( frTrasf) ;
|
||||
|
||||
// porto i dati di scorrimento nel riferimento del gruppo
|
||||
Point3d ptOnLoc = ptOn ;
|
||||
@@ -554,9 +598,9 @@ SurfFlatRegion::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector
|
||||
vtDirLoc.ToLoc( m_frF) ;
|
||||
|
||||
// ciclo sugli oggetti
|
||||
bool bOk = m_pExtLoop->Shear( ptOnLoc, vtNormLoc, vtDirLoc, dCoeff) ;
|
||||
for ( auto& pIntLoop : m_vpIntLoop) {
|
||||
if ( ! pIntLoop->Shear( ptOnLoc, vtNormLoc, vtDirLoc, dCoeff))
|
||||
bool bOk = true ;
|
||||
for ( auto& pLoop : m_vpLoop) {
|
||||
if ( ! pLoop->Shear( ptOnLoc, vtNormLoc, vtDirLoc, dCoeff))
|
||||
bOk = false ;
|
||||
}
|
||||
|
||||
@@ -568,24 +612,16 @@ bool
|
||||
SurfFlatRegion::ConvertArcsToBezierCurves( void)
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_pExtLoop == nullptr)
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// loop esterno
|
||||
if ( m_pExtLoop->GetType() == CRV_ARC) {
|
||||
ICurve* pCrvNew = ArcToBezierCurve( m_pExtLoop) ;
|
||||
if ( pCrvNew == nullptr)
|
||||
return false ;
|
||||
delete m_pExtLoop ;
|
||||
m_pExtLoop = pCrvNew ;
|
||||
}
|
||||
// eventuali loop interni
|
||||
for ( auto& pIntLoop : m_vpIntLoop) {
|
||||
if ( pIntLoop->GetType() == CRV_ARC) {
|
||||
ICurve* pCrvNew = ArcToBezierCurve( pIntLoop) ;
|
||||
// ciclo sui loop
|
||||
for ( auto& pLoop : m_vpLoop) {
|
||||
if ( pLoop->GetType() == CRV_ARC) {
|
||||
ICurve* pCrvNew = ArcToBezierCurve( pLoop) ;
|
||||
if ( pCrvNew == nullptr)
|
||||
return false ;
|
||||
delete pIntLoop ;
|
||||
pIntLoop = pCrvNew ;
|
||||
delete pLoop ;
|
||||
pLoop = pCrvNew ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
@@ -634,13 +670,13 @@ SurfFlatRegion::GetArea( double& dArea) const
|
||||
// inizio con area nulla
|
||||
dArea = 0 ;
|
||||
// la regione deve essere validata
|
||||
if ( m_nStatus != OK || m_pExtLoop == nullptr)
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// sommo l'area di tutti i loop (gli interni hanno area negativa)
|
||||
bool bOk = m_pExtLoop->GetAreaXY( dArea) ;
|
||||
for ( auto& pIntLoop : m_vpIntLoop) {
|
||||
bool bOk = true ;
|
||||
for ( auto& pLoop : m_vpLoop) {
|
||||
double dTemp ;
|
||||
if ( pIntLoop->GetAreaXY( dTemp))
|
||||
if ( pLoop->GetAreaXY( dTemp))
|
||||
dArea += dTemp ;
|
||||
else
|
||||
bOk = false ;
|
||||
@@ -657,35 +693,111 @@ SurfFlatRegion::GetCentroid( Point3d& ptCen) const
|
||||
if ( &ptCen == nullptr)
|
||||
return false ;
|
||||
// la regione deve essere validata
|
||||
if ( m_nStatus != OK || m_pExtLoop == nullptr)
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// determino il centroide del solo loop esterno
|
||||
return m_pExtLoop->GetCentroid( ptCen) ;
|
||||
if ( ! m_vpLoop[0]->GetCentroid( ptCen))
|
||||
return false ;
|
||||
// lo porto dal riferimento intrinseco a quello in cui è immersa l'entità
|
||||
ptCen.ToGlob( m_frF) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfFlatRegion::GetChunkCount( void) const
|
||||
{
|
||||
// la regione deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return 0 ;
|
||||
return int( m_vExtInd.size()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfFlatRegion::GetLoopCount( int nChunk) const
|
||||
{
|
||||
// la regione deve essere validata
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return 0 ;
|
||||
// non deve superare l'indice massimo ( Count - 1)
|
||||
int nChunkMax = int( m_vExtInd.size()) - 1 ;
|
||||
if ( nChunk < 0 || nChunk > nChunkMax)
|
||||
return 0 ;
|
||||
// se non è l'ultimo Chunk
|
||||
if ( nChunk < nChunkMax)
|
||||
return ( m_vExtInd[nChunk+1] - m_vExtInd[nChunk]) ;
|
||||
// altrimenti
|
||||
else
|
||||
return ( int( m_vpLoop.size()) - m_vExtInd[nChunk]) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfFlatRegion::GetIndFromChunkLoop( int nChunk, int nLoop) const
|
||||
{
|
||||
// recupero il numero di loop nel chunk
|
||||
int nLoopCount = GetLoopCount( nChunk) ;
|
||||
if ( nLoopCount <= 0)
|
||||
return - 1 ;
|
||||
// verifico che il loop esista
|
||||
if ( nLoop < 0 || nLoop >= nLoopCount)
|
||||
return - 1 ;
|
||||
// ritorno il suo indice
|
||||
return ( m_vExtInd[nChunk] + nLoop) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::GetChunkLoopFromInd( int nInd, int& nChunk, int& nLoop) const
|
||||
{
|
||||
// valori non validi
|
||||
nChunk = - 1 ;
|
||||
nLoop = - 1 ;
|
||||
// verifico validità di nInd
|
||||
if ( nInd < 0 || nInd >= int( m_vpLoop.size()))
|
||||
return false ;
|
||||
// verifica esistenza array di chunks
|
||||
if ( m_vExtInd.empty())
|
||||
return false ;
|
||||
// ricerca del chunk e del loop
|
||||
nChunk = 0 ;
|
||||
while ( ( nChunk + 1) < int( m_vExtInd.size())) {
|
||||
if ( nInd < m_vExtInd[nChunk+1])
|
||||
break ;
|
||||
++ nChunk ;
|
||||
}
|
||||
nLoop = nInd - m_vExtInd[nChunk] ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
SurfFlatRegion::GetMyLoop( int nLoop) const
|
||||
SurfFlatRegion::GetMyLoop( int nInd) const
|
||||
{
|
||||
// la regione deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return nullptr ;
|
||||
// se esterno
|
||||
if ( nLoop == 0)
|
||||
return m_pExtLoop ;
|
||||
// altrimenti interno, verifico che l'indice sia nei limiti
|
||||
if ( nLoop < 1 || nLoop > int( m_vpIntLoop.size()))
|
||||
// verifico che l'indice sia nei limiti
|
||||
if ( nInd < 0 || nInd >= int( m_vpLoop.size()))
|
||||
return nullptr ;
|
||||
else
|
||||
return m_vpIntLoop[nLoop-1] ;
|
||||
return m_vpLoop[nInd] ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
SurfFlatRegion::GetLoop( int nLoop) const
|
||||
SurfFlatRegion::GetMyLoop( int nChunk, int nLoop) const
|
||||
{
|
||||
return GetMyLoop( GetIndFromChunkLoop( nChunk, nLoop)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
SurfFlatRegion::GetLoop( int nChunk, int nLoop) const
|
||||
{
|
||||
// recupero il loop nel riferimento intrinseco
|
||||
const ICurve* pMyCrv = GetMyLoop( nLoop) ;
|
||||
const ICurve* pMyCrv = GetMyLoop( nChunk, nLoop) ;
|
||||
if ( pMyCrv == nullptr)
|
||||
return nullptr ;
|
||||
// ne faccio una copia
|
||||
@@ -702,29 +814,37 @@ const ISurfTriMesh*
|
||||
SurfFlatRegion::GetAuxSurf( void) const
|
||||
{
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK || m_pExtLoop == nullptr)
|
||||
return false ;
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return nullptr ;
|
||||
// se già calcolata, la restituisco
|
||||
if ( m_pSTM != nullptr)
|
||||
if ( m_pSTM != nullptr)
|
||||
return m_pSTM ;
|
||||
// la calcolo
|
||||
// calcolo le polilinee che approssimano i loop
|
||||
POLYLINEVECTOR vPL ;
|
||||
vPL.resize( 1 + int( m_vpIntLoop.size())) ;
|
||||
int i = - 1 ;
|
||||
if ( ! m_pExtLoop->ApproxWithLines( LIN_TOL_SFR, ANG_TOL_STD_DEG, ICurve::APL_STD, vPL[++i]))
|
||||
return nullptr ;
|
||||
for ( auto& pIntLoop : m_vpIntLoop) {
|
||||
if ( ! pIntLoop->ApproxWithLines( LIN_TOL_SFR, ANG_TOL_STD_DEG, ICurve::APL_STD, vPL[++i]))
|
||||
return nullptr ;
|
||||
}
|
||||
// porto le polilinee in globale al riferimento intrinseco
|
||||
for ( auto& PL : vPL)
|
||||
PL.ToGlob( m_frF) ;
|
||||
// creo, setto la superficie trimesh ed elimino punti ripetuti
|
||||
// la creo
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL) || ! pSTM->DoCompacting())
|
||||
if ( IsNull( pSTM))
|
||||
return nullptr ;
|
||||
// per ogni chunk (componente connesso)
|
||||
for ( int i = 0 ; i < GetChunkCount() ; ++ i) {
|
||||
// calcolo le polilinee che approssimano i loop
|
||||
POLYLINEVECTOR vPL ;
|
||||
vPL.resize( GetLoopCount( i)) ;
|
||||
int j = 0 ;
|
||||
ICurve* pLoop = GetMyLoop( i, j) ;
|
||||
while ( pLoop != nullptr) {
|
||||
if ( ! pLoop->ApproxWithLines( LIN_TOL_SFR, ANG_TOL_STD_DEG, ICurve::APL_STD, vPL[j]))
|
||||
return nullptr ;
|
||||
pLoop = GetMyLoop( i, ++j) ;
|
||||
}
|
||||
// porto le polilinee in globale al riferimento intrinseco
|
||||
for ( auto& PL : vPL)
|
||||
PL.ToGlob( m_frF) ;
|
||||
// creo, setto la superficie trimesh ed elimino punti ripetuti
|
||||
PtrOwner<SurfTriMesh> pChSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pChSTM) || ! pChSTM->CreateByRegion( vPL) || ! pChSTM->DoCompacting())
|
||||
return nullptr ;
|
||||
// inserisco questa trimesh in quella complessiva
|
||||
pSTM->DoSewing( *Get( pChSTM)) ;
|
||||
}
|
||||
// la salvo
|
||||
m_pSTM = Release( pSTM) ;
|
||||
return m_pSTM ;
|
||||
@@ -739,16 +859,47 @@ SurfFlatRegion::ResetAuxSurf( void) const
|
||||
m_pSTM = nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
SurfFlatRegion*
|
||||
SurfFlatRegion::CloneChunk( int nChunk) const
|
||||
{
|
||||
// verifico esistenza del chunk (implicitamente anche lo stato)
|
||||
int nLoop = GetLoopCount( nChunk) ;
|
||||
if ( nLoop == 0)
|
||||
return nullptr ;
|
||||
// alloco la nuova regione
|
||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr))
|
||||
return nullptr ;
|
||||
// copio il riferimento intrinseco
|
||||
pSfr->m_frF = m_frF ;
|
||||
// copio i loop del chunk indicato
|
||||
for ( int i = 0 ; i < nLoop ; ++i) {
|
||||
ICurve* pCrv = GetMyLoop( nChunk, i)->Clone() ;
|
||||
if ( pCrv == nullptr)
|
||||
return nullptr ;
|
||||
pSfr->m_vpLoop.push_back( pCrv) ;
|
||||
}
|
||||
// sistemo indice dell'unico loop esterno
|
||||
pSfr->m_vExtInd.push_back( 0) ;
|
||||
pSfr->m_nStatus = OK ;
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_pExtLoop == nullptr)
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// verifico la curva
|
||||
if ( &Crv == nullptr || ! Crv.IsValid())
|
||||
return false ;
|
||||
// dominio della curva
|
||||
double dStart, dEnd ;
|
||||
if ( ! Crv.GetDomain( dStart, dEnd))
|
||||
return false ;
|
||||
// curva in locale nel riferimento intrinseco
|
||||
const ICurve* pCrvLoc = nullptr ;
|
||||
PtrOwner<ICurve> pCopyCrv ;
|
||||
@@ -761,72 +912,77 @@ SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass)
|
||||
pCopyCrv->ToLoc( m_frF) ;
|
||||
pCrvLoc = Get( pCopyCrv) ;
|
||||
}
|
||||
// intervalli delle diverse classi
|
||||
Intervals inIn, inOut, inOnP, inOnM ;
|
||||
// classifico la curva con tutti i loop presenti
|
||||
int nLoop = 0 ;
|
||||
const ICurve* pLoop = GetMyLoop( nLoop) ;
|
||||
while ( pLoop != nullptr) {
|
||||
// intersezione
|
||||
IntersCurveCurve ccInt( *pCrvLoc, *pLoop) ;
|
||||
// classificazione
|
||||
CRVCVECTOR ccPart ;
|
||||
if ( ! ccInt.GetCurveClassification( 0, ccPart))
|
||||
return false ;
|
||||
for ( auto& ccOne : ccPart) {
|
||||
switch ( ccOne.nClass) {
|
||||
case CRVC_IN : inIn.Add( ccOne.dParS, ccOne.dParE) ; break ;
|
||||
case CRVC_OUT : inOut.Add( ccOne.dParS, ccOne.dParE) ; break ;
|
||||
case CRVC_ON_P : inOnP.Add( ccOne.dParS, ccOne.dParE) ; break ;
|
||||
case CRVC_ON_M : inOnM.Add( ccOne.dParS, ccOne.dParE) ; break ;
|
||||
default : return false ;
|
||||
|
||||
// intervalli totali delle diverse classi
|
||||
Intervals inTIn, inTOut, inTOnP, inTOnM ;
|
||||
inTOut.Set( dStart, dEnd) ; // inizializzo come tutta la linea per poi poter rimuovere parti
|
||||
// ciclo sui chunk
|
||||
for ( int nChunk = 0 ; nChunk < GetChunkCount() ; ++ nChunk) {
|
||||
// intervalli di Chunk delle diverse classi
|
||||
Intervals inCIn, inCOut, inCOnP, inCOnM ;
|
||||
inCIn.Set( dStart, dEnd) ; // inizializzo come tutta la linea per poi poter rimuovere parti
|
||||
// classifico la curva con tutti i loop presenti nel chunk
|
||||
for ( int nLoop = 0 ; nLoop < GetLoopCount( nChunk) ; ++ nLoop) {
|
||||
const ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
|
||||
// intersezione
|
||||
IntersCurveCurve ccInt( *pCrvLoc, *pLoop) ;
|
||||
// classificazione
|
||||
CRVCVECTOR ccPart ;
|
||||
if ( ! ccInt.GetCurveClassification( 0, ccPart))
|
||||
return false ;
|
||||
for ( auto& ccOne : ccPart) {
|
||||
switch ( ccOne.nClass) {
|
||||
case CRVC_IN :
|
||||
// IN è Remove degli altri
|
||||
break ;
|
||||
case CRVC_OUT :
|
||||
inCOut.Add( ccOne.dParS, ccOne.dParE) ;
|
||||
inCIn.Remove( ccOne.dParS, ccOne.dParE) ;
|
||||
break ;
|
||||
case CRVC_ON_P :
|
||||
inCOnP.Add( ccOne.dParS, ccOne.dParE) ;
|
||||
inCIn.Remove( ccOne.dParS, ccOne.dParE) ;
|
||||
break ;
|
||||
case CRVC_ON_M :
|
||||
inCOnM.Add( ccOne.dParS, ccOne.dParE) ;
|
||||
inCIn.Remove( ccOne.dParS, ccOne.dParE) ;
|
||||
break ;
|
||||
default : return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// passo al loop successivo
|
||||
++ nLoop ;
|
||||
pLoop = GetMyLoop( nLoop) ;
|
||||
}
|
||||
// sistemo gli intervalli di classificazione
|
||||
// Out prevale su tutto
|
||||
double dMin, dMax ;
|
||||
bool bFound = inOut.GetFirst( dMin, dMax) ;
|
||||
while ( bFound) {
|
||||
inIn.Remove( dMin, dMax) ;
|
||||
inOnP.Remove( dMin, dMax) ;
|
||||
inOnM.Remove( dMin, dMax) ;
|
||||
bFound = inOut.GetNext( dMin, dMax) ;
|
||||
}
|
||||
// OnP e OnM prevalgono su In e sono sicuramente disgiunti tra loro
|
||||
bFound = inOnP.GetFirst( dMin, dMax) ;
|
||||
while ( bFound) {
|
||||
inIn.Remove( dMin, dMax) ;
|
||||
bFound = inOnP.GetNext( dMin, dMax) ;
|
||||
}
|
||||
bFound = inOnM.GetFirst( dMin, dMax) ;
|
||||
while ( bFound) {
|
||||
inIn.Remove( dMin, dMax) ;
|
||||
bFound = inOnM.GetNext( dMin, dMax) ;
|
||||
// aggiorno gli intervalli di classificazione totali
|
||||
// In, OnP e OnM vengono aggiornati per somma
|
||||
inTIn.Union( inCIn) ;
|
||||
inTOnP.Union( inCOnP) ;
|
||||
inTOnM.Union( inCOnM) ;
|
||||
// Out viene ricavato per differenza degli altri
|
||||
inTOut.Difference( inCIn) ;
|
||||
inTOut.Difference( inCOnP) ;
|
||||
inTOut.Difference( inCOnM) ;
|
||||
}
|
||||
|
||||
// ricostruisco la classificazione completa e la ordino
|
||||
bFound = inIn.GetFirst( dMin, dMax) ;
|
||||
double dMin, dMax ;
|
||||
bool bFound = inTIn.GetFirst( dMin, dMax) ;
|
||||
while ( bFound) {
|
||||
ccClass.emplace_back( dMin, dMax, CRVC_IN) ;
|
||||
bFound = inIn.GetNext( dMin, dMax) ;
|
||||
bFound = inTIn.GetNext( dMin, dMax) ;
|
||||
}
|
||||
bFound = inOut.GetFirst( dMin, dMax) ;
|
||||
bFound = inTOut.GetFirst( dMin, dMax) ;
|
||||
while ( bFound) {
|
||||
ccClass.emplace_back( dMin, dMax, CRVC_OUT) ;
|
||||
bFound = inOut.GetNext( dMin, dMax) ;
|
||||
bFound = inTOut.GetNext( dMin, dMax) ;
|
||||
}
|
||||
bFound = inOnP.GetFirst( dMin, dMax) ;
|
||||
bFound = inTOnP.GetFirst( dMin, dMax) ;
|
||||
while ( bFound) {
|
||||
ccClass.emplace_back( dMin, dMax, CRVC_ON_P) ;
|
||||
bFound = inOnP.GetNext( dMin, dMax) ;
|
||||
bFound = inTOnP.GetNext( dMin, dMax) ;
|
||||
}
|
||||
bFound = inOnM.GetFirst( dMin, dMax) ;
|
||||
bFound = inTOnM.GetFirst( dMin, dMax) ;
|
||||
while ( bFound) {
|
||||
ccClass.emplace_back( dMin, dMax, CRVC_ON_M) ;
|
||||
bFound = inOnM.GetNext( dMin, dMax) ;
|
||||
bFound = inTOnM.GetNext( dMin, dMax) ;
|
||||
}
|
||||
sort( ccClass.begin(), ccClass.end(),
|
||||
[]( const CrvClass& a, const CrvClass& b) { return a.dParS < b.dParS ; }) ;
|
||||
|
||||
+14
-11
@@ -71,14 +71,17 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
||||
public : // ISurfFlatRegion
|
||||
virtual bool CopyFrom( const IGeoObj* pGObjSrc) ;
|
||||
virtual bool Clear( void) ;
|
||||
virtual bool SetExtLoop( const ICurve& cCrv) ;
|
||||
virtual bool SetExtLoop( ICurve* pCrv) ;
|
||||
virtual bool AddExtLoop( const ICurve& cCrv) ;
|
||||
virtual bool AddExtLoop( ICurve* pCrv) ;
|
||||
virtual bool AddIntLoop( const ICurve& cCrv) ;
|
||||
virtual bool AddIntLoop( ICurve* pCrv) ;
|
||||
virtual ICurve* GetLoop( int nLoop) const ; // nLoop=0 esterno, successivi interni
|
||||
virtual int GetIntLoopNumber( void) const
|
||||
{ return int( m_vpIntLoop.size()) ; }
|
||||
virtual const Vector3d& GetNormVersor( void) const
|
||||
{ return m_frF.VersZ() ; }
|
||||
virtual int GetChunkCount( void) const ;
|
||||
virtual int GetLoopCount( int nChunk) const ;
|
||||
virtual ICurve* GetLoop( int nChunk, int nLoop) const ; // nChunk 0-based, nLoop 0-based (1°esterno, successivi interni)
|
||||
virtual const ISurfTriMesh* GetAuxSurf( void) const ;
|
||||
virtual SurfFlatRegion* CloneChunk( int nChunk) const ;
|
||||
virtual bool GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
@@ -97,7 +100,10 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
||||
return *this ; }
|
||||
private :
|
||||
bool CopyFrom( const SurfFlatRegion& clSrc) ;
|
||||
virtual ICurve* GetMyLoop( int nLoop) const ; // nLoop=0 esterno, successivi interni
|
||||
int GetIndFromChunkLoop( int nChunk, int nLoop) const ;
|
||||
bool GetChunkLoopFromInd( int nInd, int& nChunk, int& nLoop) const ;
|
||||
ICurve* GetMyLoop( int nInd) const ; // indice nel vettore di tutti i loop
|
||||
ICurve* GetMyLoop( int nChunk, int nLoop) const ; // nChunk 0-based, nLoop 0-based (1°esterno, successivi interni)
|
||||
void ResetAuxSurf( void) const ;
|
||||
bool ConvertArcsToBezierCurves( void) ;
|
||||
|
||||
@@ -106,18 +112,15 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
||||
|
||||
private :
|
||||
typedef std::deque<ICurve*> PCRV_DEQUE ;
|
||||
typedef PCRV_DEQUE::iterator PCRD_ITER ;
|
||||
typedef PCRV_DEQUE::const_iterator PCRD_CONST_ITER ;
|
||||
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
mutable SurfTriMesh* m_pSTM ; // superficie trimesh ausiliaria
|
||||
Status m_nStatus ; // stato
|
||||
Frame3d m_frF ; // riferimento intrinseco
|
||||
ICurve* m_pExtLoop ; // curva che forma il loop esterno
|
||||
PCRV_DEQUE m_vpIntLoop ; // deque delle curve che formano i loop interni
|
||||
PCRV_DEQUE m_vpLoop ; // deque delle curve che formano i loop
|
||||
INTVECTOR m_vExtInd ; // indice dei loop esterni nel precedente vettore
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
mutable PCRD_CONST_ITER m_Iter ; // iteratore sui loop interni
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
+5
-5
@@ -283,7 +283,7 @@ SurfTriMesh::GetCentroid( Point3d& ptCen) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetVertexNum( void) const
|
||||
SurfTriMesh::GetVertexCount( void) const
|
||||
{
|
||||
// calcolo il numero dei vertici cancellati
|
||||
int nErased = 0 ;
|
||||
@@ -297,7 +297,7 @@ SurfTriMesh::GetVertexNum( void) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetTriangleNum( void) const
|
||||
SurfTriMesh::GetTriangleCount( void) const
|
||||
{
|
||||
// calcolo il numero dei triangoli cancellati
|
||||
int nErased = 0 ;
|
||||
@@ -682,14 +682,14 @@ SurfTriMesh::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
||||
if ( ! m_bOriented)
|
||||
sOut += string( "Inconsistent Orientation") + szNewLine ;
|
||||
// numero di vertici
|
||||
sOut += "Vert : Nbr=" + ToString( GetVertexNum()) +
|
||||
sOut += "Vert : Nbr=" + ToString( GetVertexCount()) +
|
||||
" Size=" + ToString( GetVertexSize()) + szNewLine ;
|
||||
// numero di triangoli
|
||||
sOut += "Tria : Nbr=" + ToString( GetTriangleNum()) +
|
||||
sOut += "Tria : Nbr=" + ToString( GetTriangleCount()) +
|
||||
" Size=" + ToString( GetTriangleSize()) + szNewLine ;
|
||||
// numero facce, se calcolate
|
||||
if ( m_bFaceted)
|
||||
sOut += "Facet : Nbr=" + ToString( GetFacetNum()) +
|
||||
sOut += "Facet : Nbr=" + ToString( GetFacetCount()) +
|
||||
" Size=" + ToString( GetFacetSize()) + szNewLine ;
|
||||
|
||||
return true ;
|
||||
|
||||
+3
-3
@@ -139,8 +139,8 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
double dAngRot, double dStepRot, double dMove) ;
|
||||
virtual bool DoCompacting( void) ;
|
||||
virtual bool DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther = GLOB_FRM) ;
|
||||
virtual int GetVertexNum( void) const ;
|
||||
virtual int GetTriangleNum( void) const ;
|
||||
virtual int GetVertexCount( void) const ;
|
||||
virtual int GetTriangleCount( void) const ;
|
||||
virtual int GetVertexSize( void) const
|
||||
{ return int( m_vVert.size()) ; }
|
||||
virtual int GetTriangleSize( void) const
|
||||
@@ -162,7 +162,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
virtual bool GetVertexSmoothNormal( int nV, int nT, Vector3d& vtN) const ;
|
||||
virtual bool GetTriangleBoundaryEdges( int nId, TriFlags3d& TFlags) const ;
|
||||
virtual bool GetTriangleSmoothNormals( int nId, TriNormals3d& TNrms) const ;
|
||||
virtual int GetFacetNum( void) const ;
|
||||
virtual int GetFacetCount( void) const ;
|
||||
virtual int GetFacetSize( void) const
|
||||
{ return int( m_vFacet.size()) ; }
|
||||
virtual int GetFacetFromTria( int nT) const ;
|
||||
|
||||
@@ -119,7 +119,7 @@ SurfTriMesh::UpdateTriaFaceting( int nRefT, int nFacet, const Plane3d& plPlane,
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::GetFacetNum( void) const
|
||||
SurfTriMesh::GetFacetCount( void) const
|
||||
{
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
|
||||
Reference in New Issue
Block a user