EgtGeomKernel 2.2j1 :
- operazione booleane su TriMesh eseguite con scalatura di 1024.
This commit is contained in:
Binary file not shown.
+30
-6
@@ -104,7 +104,8 @@ Polygon3d::FromPolyLine( const PolyLine& PL)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Polygon3d::FromPlaneTrimmedWithBox( const Plane3d& plPlane, const Point3d& ptMin, const Point3d& ptMax, bool bOnEq, bool bOnCt)
|
||||
Polygon3d::FromPlaneTrimmedWithBox( const Plane3d& plPlane,
|
||||
const Point3d& ptMin, const Point3d& ptMax, bool bOnEq, bool bOnCt, double dToler)
|
||||
{
|
||||
// pulisco tutto
|
||||
Clear() ;
|
||||
@@ -112,17 +113,32 @@ Polygon3d::FromPlaneTrimmedWithBox( const Plane3d& plPlane, const Point3d& ptMin
|
||||
if ( plPlane.GetVersN().IsSmall() || AreSamePointApprox( ptMin, ptMax))
|
||||
return false ;
|
||||
// assegno il piano
|
||||
m_Plane = plPlane ;
|
||||
Plane3d plTemp = plPlane ;
|
||||
// se piano molto vicino ad uno dei vertici del box, lo faccio passare esattamente per il vertice
|
||||
if ( dToler > EPS_SMALL) {
|
||||
PNTVECTOR vBoxVert = { Point3d( ptMin.x, ptMin.y, ptMin.z), Point3d( ptMin.x, ptMin.y, ptMax.z),
|
||||
Point3d( ptMax.x, ptMin.y, ptMin.z), Point3d( ptMax.x, ptMin.y, ptMax.z),
|
||||
Point3d( ptMin.x, ptMax.y, ptMin.z), Point3d( ptMin.x, ptMax.y, ptMax.z),
|
||||
Point3d( ptMax.x, ptMax.y, ptMin.z), Point3d( ptMax.x, ptMax.y, ptMax.z)} ;
|
||||
for ( const auto& ptP : vBoxVert) {
|
||||
if ( abs( DistPointPlane( ptP, plTemp)) < dToler) {
|
||||
Point3d ptNear = ProjectPointOnPlane( ptP, plTemp) ;
|
||||
Vector3d vtDelta = ptP - ptNear ;
|
||||
plTemp.Offset( vtDelta * plTemp.GetVersN()) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// centro del box proiettato nel piano
|
||||
Point3d ptCen = Media( ptMin, ptMax, 0.5) ;
|
||||
ptCen -= (( ptCen - ORIG) * plPlane.GetVersN() - plPlane.GetDist()) * plPlane.GetVersN() ;
|
||||
ptCen -= (( ptCen - ORIG) * plTemp.GetVersN() - plTemp.GetDist()) * plTemp.GetVersN() ;
|
||||
// raggio del box
|
||||
double dDiam = Dist( ptMin, ptMax) ;
|
||||
// poligono nel suo piano
|
||||
FromRectangle( dDiam, dDiam) ;
|
||||
// riferimento del piano
|
||||
Frame3d frRef ;
|
||||
frRef.Set( ptCen, plPlane.GetVersN(), FromUprightOrtho( plPlane.GetVersN())) ;
|
||||
frRef.Set( ptCen, plTemp.GetVersN(), FromUprightOrtho( plTemp.GetVersN())) ;
|
||||
ToGlob( frRef) ;
|
||||
// lo trimmo con le facce del box
|
||||
Plane3d plFace ;
|
||||
@@ -138,14 +154,22 @@ Polygon3d::FromPlaneTrimmedWithBox( const Plane3d& plPlane, const Point3d& ptMin
|
||||
Trim( plFace, true, bOnEq, bOnCt) ;
|
||||
plFace.Set( ptMax.x, X_AX) ; // faccia 6 (Norm = X+)
|
||||
Trim( plFace, true, bOnEq, bOnCt) ;
|
||||
|
||||
// elimino eventuali vertici coincidenti
|
||||
for ( int i = 1 ; i < int( m_vVert.size()) ;) {
|
||||
if ( SqDist( m_vVert[i], m_vVert[i-1]) < SQ_EPS_SMALL) {
|
||||
m_vVert[i-1] = Media( m_vVert[i-1], m_vVert[i]) ;
|
||||
m_vVert.erase( m_vVert.begin() + i) ;
|
||||
}
|
||||
else
|
||||
++ i ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Polygon3d::FromPlaneTrimmedWithBox( const Point3d& ptOn, const Vector3d& vtN,
|
||||
const Point3d& ptMin, const Point3d& ptMax, bool bOnEq, bool bOnCt)
|
||||
const Point3d& ptMin, const Point3d& ptMax, bool bOnEq, bool bOnCt, double dToler)
|
||||
{
|
||||
Plane3d plPlane ;
|
||||
plPlane.Set( ptOn, vtN) ;
|
||||
|
||||
+147
-8
@@ -1,13 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2019-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfTriMeshBooleans.cpp Data : 04.04.20 Versione : 2.2d1
|
||||
// File : SurfTriMeshBooleans.cpp Data : 01.10.20 Versione : 2.2j1
|
||||
// Contenuto : Implementazione delle funzioni booleane per SurfFTrimesh.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 10.05.19 LM Creazione modulo.
|
||||
//
|
||||
// 01.10.20 LM Aggiunte scalature 1024x.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -955,7 +955,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
|
||||
// Creo i loop
|
||||
ChainCurves LoopCreator ;
|
||||
LoopCreator.Init( false, EPS_SMALL, int( it->second.size())) ;
|
||||
LoopCreator.Init( false, 10 * EPS_SMALL, int( it->second.size())) ;
|
||||
// Carico le curve per concatenarle
|
||||
for ( int nCv = 0 ; nCv < int( it->second.size()); ++ nCv) {
|
||||
Point3d ptSt = it->second[nCv].ptSt ;
|
||||
@@ -1390,7 +1390,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
|
||||
// Aggiungo al loop esterno i punti dei loop interni che si trovano su di esso
|
||||
PNTULIST ExternLoopList = vPolygons[0].GetUPointList() ;
|
||||
PNTULIST& ExternLoopList = vPolygons[0].GetUPointList() ;
|
||||
// Ciclo sui segmenti del loop esterno
|
||||
auto itSt = ExternLoopList.begin() ;
|
||||
auto itEn = itSt ;
|
||||
@@ -1408,6 +1408,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
for ( int nInnPoly = 1 ; nInnPoly < int( vPolygons.size()) ; ++ nInnPoly) {
|
||||
// Ciclo sui punti dei loop interni
|
||||
Point3d ptInnPoint ;
|
||||
bool bIsFirst = true ;
|
||||
bool bContinue = vPolygons[nInnPoly].GetFirstPoint( ptInnPoint) ;
|
||||
while ( bContinue) {
|
||||
DistPointLine DistCalculator( ptInnPoint, ptSt, ptEn) ;
|
||||
@@ -1418,8 +1419,10 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
POINTU NewPointU ;
|
||||
NewPointU.first = ptInnPoint ;
|
||||
NewPointU.second = dLongPos ;
|
||||
vPointWithOrder.emplace_back( NewPointU) ;
|
||||
if ( ! bIsFirst)
|
||||
vPointWithOrder.emplace_back( NewPointU) ;
|
||||
}
|
||||
bIsFirst = false ;
|
||||
bContinue = vPolygons[nInnPoly].GetNextPoint( ptInnPoint) ;
|
||||
}
|
||||
}
|
||||
@@ -1459,7 +1462,120 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
}
|
||||
}
|
||||
// Divido i loop che si autointercettano
|
||||
int nInitialLoopNum = int( vPolygons.size()) ;
|
||||
for ( int nL = 1 ; nL < nInitialLoopNum ; ++ nL) {
|
||||
// Lista dei punti della PolyLine Loop corrente
|
||||
PNTULIST& LoopPointList = vPolygons[nL].GetUPointList() ;
|
||||
// Ciclo sui segmenti
|
||||
auto itSt = LoopPointList.begin() ;
|
||||
auto itEn = itSt ;
|
||||
++ itEn ;
|
||||
for ( ; itSt != LoopPointList.end() && itEn != LoopPointList.end() ; ++ itSt, ++ itEn) {
|
||||
// Segmento corrente
|
||||
Point3d ptSt = itSt->first ;
|
||||
Point3d ptEn = itEn->first ;
|
||||
Vector3d vtSeg = ptEn - ptSt ;
|
||||
double dSegLen = vtSeg.Len() ;
|
||||
vtSeg /= dSegLen ;
|
||||
// Lista di punti da aggiungere al segmento corrente
|
||||
PNTUVECTOR vAddingPointWithOrder ;
|
||||
// Ciclo su tutti i punti non del segmento corrente
|
||||
auto itP = LoopPointList.begin() ;
|
||||
for ( ; itP != LoopPointList.end() ; ++ itP) {
|
||||
if ( itP != itSt && itP != itEn) {
|
||||
Point3d ptP = itP->first ;
|
||||
DistPointLine DistCalculator( ptP, ptSt, ptEn) ;
|
||||
double dDist ;
|
||||
DistCalculator.GetDist( dDist) ;
|
||||
double dLongPos = ( ptP - ptSt) * vtSeg ;
|
||||
if ( dDist < EPS_SMALL && dLongPos > 0. && dLongPos < dSegLen) {
|
||||
POINTU NewPointU ;
|
||||
NewPointU.first = ptP ;
|
||||
NewPointU.second = dLongPos ;
|
||||
vAddingPointWithOrder.emplace_back( NewPointU) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Riordino i punti interni sul segmento esterno in funzione della distanza dall'origine di esso
|
||||
for ( int nPi = 0 ; nPi < int( vAddingPointWithOrder.size()) - 1 ; ++ nPi) {
|
||||
for ( int nPj = nPi + 1 ; nPj < int( vAddingPointWithOrder.size()) ; ++ nPj) {
|
||||
if ( vAddingPointWithOrder[nPi].second > vAddingPointWithOrder[nPj].second) {
|
||||
swap( vAddingPointWithOrder[nPi], vAddingPointWithOrder[nPj]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Aggiungo i punti al loop esterno
|
||||
for ( int nPi = 0 ; nPi < int( vAddingPointWithOrder.size()) ; ++ nPi) {
|
||||
itSt = LoopPointList.emplace( itEn, vAddingPointWithOrder[nPi]) ;
|
||||
}
|
||||
}
|
||||
// Spezzo i loop autointersecantesi
|
||||
|
||||
POLYLINEVECTOR vAuxPolygons ;
|
||||
vAuxPolygons.emplace_back( vPolygons[nL]) ;
|
||||
|
||||
bool bSplitted = true ;
|
||||
while ( bSplitted) {
|
||||
bSplitted = false ;
|
||||
for ( int nl = 0 ; nl < int( vAuxPolygons.size()) ; ++ nl) {
|
||||
PNTULIST& PntLst = vAuxPolygons[nl].GetUPointList() ;
|
||||
std::vector<Point3d> vPoint ;
|
||||
for ( auto it = PntLst.begin() ; it != PntLst.end() ; ++ it) {
|
||||
vPoint.emplace_back( it->first) ;
|
||||
}
|
||||
int nStartPt = -1 ;
|
||||
int nEndPt = int( vPoint.size()) ;
|
||||
for ( int ni = 0 ; ni < int( vPoint.size()) - 1 ; ++ ni) {
|
||||
for ( int nj = ni + 1 ; nj < int( vPoint.size()) ; ++ nj) {
|
||||
if ( ( ni != 0 || nj != int( vPoint.size()) - 1) &&
|
||||
AreSamePointApprox( vPoint[ni], vPoint[nj])) {
|
||||
nStartPt = ni ;
|
||||
nEndPt = nj ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( nStartPt != -1 && nEndPt != int( vPoint.size())) {
|
||||
PolyLine CurAuxLoop1, CurAuxLoop2 ;
|
||||
for ( int ni = 0 ; ni < int( vPoint.size()) ; ++ ni) {
|
||||
if ( ni < nStartPt || ni >= nEndPt)
|
||||
CurAuxLoop1.AddUPoint( 0., vPoint[ni]) ;
|
||||
else
|
||||
CurAuxLoop2.AddUPoint( 0., vPoint[ni]) ;
|
||||
}
|
||||
CurAuxLoop2.AddUPoint( 0., vPoint[nStartPt]) ;
|
||||
vAuxPolygons[nl].Clear() ;
|
||||
Point3d ptP ;
|
||||
bool bContinue = CurAuxLoop1.GetFirstPoint( ptP) ;
|
||||
while ( bContinue) {
|
||||
vAuxPolygons[nl].AddUPoint( 0., ptP) ;
|
||||
bContinue = CurAuxLoop1.GetNextPoint( ptP) ;
|
||||
}
|
||||
vAuxPolygons.emplace_back( CurAuxLoop2) ;
|
||||
bSplitted = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool bReplaced = false ;
|
||||
for ( int nl = 0 ; nl < int( vAuxPolygons.size()) ; ++ nl) {
|
||||
if ( true/*vAuxPolygons.GetAreaXY(double& dArea)*/) {
|
||||
if ( ! bReplaced) {
|
||||
vPolygons[nL].Clear() ;
|
||||
Point3d ptP ;
|
||||
bool bContinue = vAuxPolygons[nl].GetFirstPoint( ptP) ;
|
||||
while ( bContinue) {
|
||||
vPolygons[nL].AddUPoint( 0., ptP) ;
|
||||
bContinue = vAuxPolygons[nl].GetNextPoint( ptP) ;
|
||||
}
|
||||
bReplaced = true ;
|
||||
}
|
||||
else {
|
||||
vPolygons.emplace_back( vAuxPolygons[nl]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( int nL = 1 ; nL < int( vPolygons.size()) ; ++ nL) {
|
||||
vPolygons[nL].Invert() ;
|
||||
if ( Triangulate().Make( vPolygons[nL], vPt, vTr)) {
|
||||
@@ -2270,6 +2386,10 @@ SurfTriMesh::Add( const ISurfTriMesh& Other)
|
||||
m_OGrMgr.Clear() ;
|
||||
SurfTriMesh SurfB ;
|
||||
SurfB.CopyFrom( &Other) ;
|
||||
Frame3d frScalingRef ;
|
||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||
Scale( frScalingRef, 1024., 1024., 1024.) ;
|
||||
SurfB.Scale( frScalingRef, 1024., 1024., 1024.) ;
|
||||
IntersectTriMeshTriangle( SurfB) ;
|
||||
IdentifyParts() ;
|
||||
SurfB.IdentifyParts() ;
|
||||
@@ -2297,7 +2417,9 @@ SurfTriMesh::Add( const ISurfTriMesh& Other)
|
||||
if ( ! AdjustVertices() || ! DoCompacting())
|
||||
return false ;
|
||||
RemoveTJunctions() ;
|
||||
return ( AdjustVertices() && DoCompacting()) ;
|
||||
bool bResult = ( AdjustVertices() && DoCompacting()) ;
|
||||
Scale( frScalingRef, 1. / 1024., 1. / 1024., 1. / 1024.) ;
|
||||
return bResult ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -2307,6 +2429,10 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other)
|
||||
m_OGrMgr.Clear() ;
|
||||
SurfTriMesh SurfB ;
|
||||
SurfB.CopyFrom( &Other) ;
|
||||
Frame3d frScalingRef ;
|
||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||
Scale( frScalingRef, 1024., 1024., 1024.) ;
|
||||
SurfB.Scale( frScalingRef, 1024., 1024., 1024.) ;
|
||||
IntersectTriMeshTriangle( SurfB) ;
|
||||
IdentifyParts() ;
|
||||
SurfB.IdentifyParts() ;
|
||||
@@ -2334,7 +2460,9 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other)
|
||||
if ( ! AdjustVertices() || ! DoCompacting())
|
||||
return false ;
|
||||
RemoveTJunctions() ;
|
||||
return ( AdjustVertices() && DoCompacting()) ;
|
||||
bool bResult = ( AdjustVertices() && DoCompacting()) ;
|
||||
Scale( frScalingRef, 1. / 1024., 1. / 1024., 1. / 1024.) ;
|
||||
return bResult ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -2344,6 +2472,10 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other)
|
||||
m_OGrMgr.Clear() ;
|
||||
SurfTriMesh SurfB ;
|
||||
SurfB.CopyFrom( &Other) ;
|
||||
Frame3d frScalingRef;
|
||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||
Scale( frScalingRef, 1024., 1024., 1024.) ;
|
||||
SurfB.Scale( frScalingRef, 1024., 1024., 1024.) ;
|
||||
IntersectTriMeshTriangle( SurfB) ;
|
||||
IdentifyParts() ;
|
||||
SurfB.IdentifyParts() ;
|
||||
@@ -2372,7 +2504,9 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other)
|
||||
if ( ! AdjustVertices() || ! DoCompacting())
|
||||
return false ;
|
||||
RemoveTJunctions() ;
|
||||
return ( AdjustVertices() && DoCompacting()) ;
|
||||
bool bResult = ( AdjustVertices() && DoCompacting()) ;
|
||||
Scale( frScalingRef, 1. / 1024., 1. / 1024., 1. / 1024.) ;
|
||||
return bResult ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -2385,8 +2519,13 @@ SurfTriMesh::GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
||||
return false ;
|
||||
SurfTriMesh SurfC ;
|
||||
SurfC.CopyFrom( &ClassifierSurf) ;
|
||||
Frame3d frScalingRef ;
|
||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||
Scale( frScalingRef, 1024., 1024., 1024.) ;
|
||||
SurfC.Scale( frScalingRef, 1024., 1024., 1024.) ;
|
||||
IntersectTriMeshTriangle( SurfC) ;
|
||||
IdentifyParts() ;
|
||||
Scale( frScalingRef, 1. / 1024., 1. / 1024., 1. / 1024.) ;
|
||||
|
||||
int nTriaNum = GetTriangleSize() ;
|
||||
for ( int nT = 0 ; nT < nTriaNum ; ++ nT) {
|
||||
|
||||
Reference in New Issue
Block a user