EgtGeomKernel :
- gestiti più chunk per la triangolaziome ( MakeAdvanced) - piccole modifiche a Intersezione e creazione di Stm da curve.
This commit is contained in:
+12
-46
@@ -790,56 +790,22 @@ bool
|
||||
CalcRegionPolyLines( const CICURVEPVECTOR& vpCurve, double dLinTol,
|
||||
POLYLINEVECTOR& vPL, Vector3d& vtN)
|
||||
{
|
||||
// se non ho curve, non faccio nulla
|
||||
if ( int( vpCurve.size()) == 0)
|
||||
return true ;
|
||||
|
||||
// calcolo le polilinee che approssimano le curve
|
||||
POLYLINEVECTOR vPLtmp ;
|
||||
vPLtmp.resize( vpCurve.size()) ;
|
||||
vPL.resize( vpCurve.size()) ;
|
||||
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
||||
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPLtmp[i]))
|
||||
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPL[i]))
|
||||
return false ;
|
||||
}
|
||||
// ne calcolo l'area e genero un ordine in senso decrescente
|
||||
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 ;
|
||||
for ( int i = 0 ; i < int( vPLtmp.size()) ; ++ i) {
|
||||
// verifico chiusura, calcolo piano medio e area
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! vPLtmp[i].IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL))
|
||||
|
||||
// ricavo versore normale
|
||||
Plane3d plPlane ; double dArea ;
|
||||
if ( ! vPL[0].IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL))
|
||||
return false ;
|
||||
// imposto la normale del primo contorno come riferimento
|
||||
if ( i == 0)
|
||||
vtN0 = plPlane.GetVersN() ;
|
||||
// verifico che le normali siano molto vicine
|
||||
if ( ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), vtN0))
|
||||
return false ;
|
||||
// assegno il segno all'area secondo il verso della normale
|
||||
if ( ( plPlane.GetVersN() * vtN0) > 0)
|
||||
vArea.emplace_back( i, dArea) ;
|
||||
else
|
||||
vArea.emplace_back( i, - dArea) ;
|
||||
}
|
||||
sort( vArea.begin(), vArea.end(),
|
||||
[]( const INDAREA& a, const INDAREA& b) { return ( abs( a.second) > abs( b.second)) ; }) ;
|
||||
// sposto le polilinee nel vettore da restituire secondo l'ordine
|
||||
vPL.clear() ;
|
||||
vPL.resize( vPLtmp.size()) ;
|
||||
bool bCCW = true ;
|
||||
for ( int i = 0 ; i < int( vPLtmp.size()) ; ++ i) {
|
||||
// scambio
|
||||
swap( vPL[i], vPLtmp[vArea[i].first]) ;
|
||||
// verifico senso di rotazione del contorno esterno
|
||||
if ( i == 0)
|
||||
bCCW = ( vArea[i].second > 0) ;
|
||||
// aggiusto gli altri contorni
|
||||
else {
|
||||
if ( ( bCCW && vArea[i].second > 0) || ( ! bCCW && vArea[i].second < 0))
|
||||
vPL[i].Invert() ;
|
||||
}
|
||||
}
|
||||
// restituisco la normale positiva alla regione
|
||||
vtN = ( bCCW ? vtN0 : - vtN0) ;
|
||||
vtN = plPlane.GetVersN() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
+1
-1
@@ -2044,7 +2044,7 @@ SurfTriMesh::CreateByRegion( const POLYLINEVECTOR& vPL)
|
||||
PNTVECTOR vPnt ;
|
||||
INTVECTOR vTria ;
|
||||
Triangulate Tri ;
|
||||
if ( ! Tri.Make( vPL, vPnt, vTria))
|
||||
if ( ! Tri.MakeAdvanced( vPL, vPnt, vTria))
|
||||
return false ;
|
||||
|
||||
// inizializzo la superficie
|
||||
|
||||
+16
-12
@@ -35,6 +35,7 @@
|
||||
#include "/EgtDev/Include/EGkPolygon3d.h"
|
||||
#include "/EgtDev/Include/EgtPerfCounter.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
@@ -731,14 +732,14 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
|
||||
Polygon3d pgPol ;
|
||||
pgPol.FromPolyLine(vPolygons[1]) ;
|
||||
pgPol.FromPolyLine( vPolygons[1]) ;
|
||||
|
||||
bool bCodirectedNormals = trTria.GetN() * pgPol.GetVersN() > 0. ;
|
||||
if ( bCodirectedNormals) {
|
||||
for ( int nL = 1 ; nL < int( vPolygons.size()) ; ++ nL) {
|
||||
vPolygons[nL].Invert() ;
|
||||
}
|
||||
}
|
||||
//if ( bCodirectedNormals) {
|
||||
// for ( int nL = 1 ; nL < int( vPolygons.size()) ; ++ nL) {
|
||||
// vPolygons[nL].Invert() ;
|
||||
// }
|
||||
//} pizza
|
||||
|
||||
// Aggiungo al loop esterno i punti dei loop interni che si trovano su di esso
|
||||
PNTULIST& ExternLoopList = vPolygons[0].GetUPointList() ;
|
||||
@@ -788,12 +789,12 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
// Aggiungo i punti al loop esterno
|
||||
for ( int nPi = 0 ; nPi < int( vPointWithOrder.size()) ; ++ nPi) {
|
||||
itSt = ExternLoopList.emplace( itEn, vPointWithOrder[nPi]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PNTVECTOR vPt ;
|
||||
INTVECTOR vTr ;
|
||||
if ( Triangulate().Make( vPolygons, vPt, vTr)) {
|
||||
if ( Triangulate().MakeAdvanced( vPolygons, vPt, vTr)) {
|
||||
// Inserisco i nuovi triangoli
|
||||
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||
int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ;
|
||||
@@ -928,9 +929,11 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( int nL = 1 ; nL < int( vPolygons.size()) ; ++ nL) {
|
||||
vPolygons[nL].Invert() ;
|
||||
if ( Triangulate().Make( vPolygons[nL], vPt, vTr)) {
|
||||
// pizza
|
||||
//for ( int nL = 1 ; nL < int( vPolygons.size()) ; ++ nL) {
|
||||
// vPolygons[nL].Invert() ;
|
||||
vPolygons.erase( vPolygons.begin()) ;
|
||||
if ( Triangulate().MakeAdvanced( vPolygons, vPt, vTr)) {
|
||||
// Inserisco i nuovi triangoli
|
||||
for (int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||
int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ;
|
||||
@@ -950,7 +953,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
vInnerLoop.resize( 0) ;
|
||||
}
|
||||
@@ -1359,6 +1362,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
// Se avvenuta modifica, aggiorno tutto
|
||||
if ( bModif)
|
||||
bContinue = ( AdjustVertices() && DoCompacting() && SurfB.AdjustVertices() && SurfB.DoCompacting()) ;
|
||||
SaveGeoObj( this, "C:\\Users\\riccardo.elitropi\\Desktop\\PocketingVolumi\\a.nge") ;
|
||||
// Triangoli sovrapposti
|
||||
if ( bContinue) {
|
||||
int nTriaNum2A = GetTriangleSize() ;
|
||||
|
||||
+137
@@ -21,8 +21,11 @@
|
||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "IntersCrvCompoCrvCompo.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -218,6 +221,140 @@ Triangulate::Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
bool
|
||||
Triangulate::MakeAdvanced( const POLYLINEVECTOR& vPLORIG, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
{
|
||||
vPt.clear() ;
|
||||
vTr.clear() ;
|
||||
// se non ho PolyLine, allora non faccio nulla
|
||||
if ( int( vPLORIG.size()) == 0)
|
||||
return true ;
|
||||
|
||||
// copio il vettore di PolyLine
|
||||
POLYLINEVECTOR vPL ;
|
||||
for ( int i = 0 ; i < int( vPLORIG.size()) ; ++ i)
|
||||
vPL.push_back( vPLORIG[i]) ;
|
||||
|
||||
typedef std::pair<int,double> INDAREA ;
|
||||
std::vector<INDAREA> m_vArea ;
|
||||
// calcolo piano medio e area delle curve
|
||||
m_vArea.reserve( vPL.size()) ;
|
||||
Vector3d vtN0 ;
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
// calcolo piano medio e area
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! vPL[i].IsClosedAndFlat( plPlane, dArea))
|
||||
return false ;
|
||||
// imposto la normale del primo contorno come riferimento
|
||||
if ( i == 0)
|
||||
vtN0 = plPlane.GetVersN() ;
|
||||
// verifico che le normali siano molto vicine
|
||||
if ( ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), vtN0))
|
||||
return false ;
|
||||
// assegno il segno all'area secondo il verso della normale
|
||||
if ( ( plPlane.GetVersN() * 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 ( abs( a.second) > abs( b.second)) ; }) ;
|
||||
|
||||
// dalle PolyLine passo alle curve nel piano XY ( prendo la prima come riferimento, trascuro le Z delle successive)
|
||||
Frame3d frRef ; frRef.Set( ORIG, vtN0) ;
|
||||
if ( ! frRef.IsValid())
|
||||
return false ;
|
||||
ICRVCOMPOPOVECTOR vCrvCompo( int( vPL.size())) ;
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
vCrvCompo[i].Set( CreateCurveComposite()) ;
|
||||
vCrvCompo[i]->FromPolyLine( vPL[i]) ;
|
||||
vCrvCompo[i]->ToLoc( frRef) ;
|
||||
}
|
||||
|
||||
// creo una matrice di interi ; ogni riga corrisponde ad un chunk, dove in posizione 0 c'è il loop esterno e nelle
|
||||
// successive i loop interni
|
||||
INTMATRIX vnPLIndMat ;
|
||||
|
||||
// aggiungo le diverse curve
|
||||
bool bExtLoop = false ;
|
||||
bool bFirstCrv ;
|
||||
Plane3d plExtLoop ;
|
||||
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 ;
|
||||
// lo inserisco come esterno...
|
||||
if ( bFirstCrv) {
|
||||
vnPLIndMat.push_back({ j}) ;
|
||||
m_vArea[i].first = -1 ;
|
||||
// inverto se necessario
|
||||
if ( m_vArea[i].second < EPS_SMALL) {
|
||||
vPL[j].Invert() ;
|
||||
vCrvCompo[j]->Invert() ;
|
||||
}
|
||||
bFirstCrv = false ;
|
||||
}
|
||||
// ... altrimenti verifico se il loop è interno o no
|
||||
else {
|
||||
// il loop è interno se è sia interno al loop esterno della riga di vnPLIndMat e allo stesso tempo
|
||||
// esterno a tutti i loop già inseriti nella riga attuale.
|
||||
// verifica rispetto loop esterno
|
||||
IntersCurveCurve ccInt( *vCrvCompo[vnPLIndMat.back().front()], *vCrvCompo[j]) ;
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt.GetCurveClassification( 1, EPS_SMALL, ccClass) ||
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||
continue ;
|
||||
// verifica rispetto ai loop interni
|
||||
bool bOk = true ;
|
||||
for ( int k = 1 ; k < int( vnPLIndMat.back().size()) ; ++ k) {
|
||||
IntersCurveCurve ccInt2( *vCrvCompo[vnPLIndMat.back()[k]], *vCrvCompo[j]) ;
|
||||
CRVCVECTOR ccClass2 ;
|
||||
if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt2.GetCurveClassification( 1, EPS_SMALL, ccClass2) ||
|
||||
ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) {
|
||||
bOk = false ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( bOk) {
|
||||
// inserisco nella matrice
|
||||
vnPLIndMat.back().push_back( j) ;
|
||||
m_vArea[i].first = -1 ;
|
||||
// inverto se necessario
|
||||
if ( m_vArea[i].second > - EPS_SMALL) {
|
||||
vPL[j].Invert() ;
|
||||
vCrvCompo[j]->Invert() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ( ! bFirstCrv) ;
|
||||
|
||||
// chiamo la Triangolazione per ogni riga della matrice ( quindi su ogni "Chunk")
|
||||
for ( int i = 0 ; i < int( vnPLIndMat.size()) ; ++ i) {
|
||||
PNTVECTOR vPt_tmp ; INTVECTOR vTr_tmp ;
|
||||
POLYLINEVECTOR vPL_tmp ;
|
||||
for ( int j = 0 ; j < int( vnPLIndMat[i].size()) ; ++ j)
|
||||
vPL_tmp.push_back( vPL[vnPLIndMat[i][j]]) ;
|
||||
if ( ! Make( vPL_tmp, vPt_tmp, vTr_tmp))
|
||||
return false ;
|
||||
int nSize = int( vPt.size()) ;
|
||||
for ( int p = 0 ; p < int( vPt_tmp.size()) ; ++ p)
|
||||
vPt.push_back( vPt_tmp[p]) ;
|
||||
for ( int t = 0 ; t < int( vTr_tmp.size()) ; ++ t)
|
||||
vTr.push_back( nSize + vTr_tmp[t]) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Triangulate the CCW n-gon specified by the vertices vPt (Pt[n] != Pt[0])
|
||||
// Ear Clipping algorithm from mapbox
|
||||
|
||||
@@ -22,6 +22,7 @@ class Triangulate
|
||||
public :
|
||||
bool Make( const PolyLine& PL, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||
bool Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||
bool MakeAdvanced( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||
|
||||
private :
|
||||
bool MakeByEC_HPP( const PolyLine& PL, bool bCCW, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||
|
||||
Reference in New Issue
Block a user