EgtGeomKernel :

- migliorie nella intersezione tra triangoli
- correzione a IntersSurfTmSurfTm che non interpretava correttamente i nuovi risultati di IntersTriaTria
- correzioni a Zmap per Mortising con movimento nel piano ma non perpendicolare all'asse dell'utensile.
This commit is contained in:
Dario Sassi
2019-11-12 07:44:51 +00:00
parent f031160066
commit 068681c474
4 changed files with 91 additions and 56 deletions
+2 -1
View File
@@ -75,7 +75,8 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
// intersezione tra i triangoli
Point3d ptInt, ptInt2 ;
TRIA3DVECTOR vIttTria ;
int nRes = IntersTriaTria( TriaA, TriaB, ptInt, ptInt2, vIttTria) ;
int nResEx = IntersTriaTria( TriaA, TriaB, ptInt, ptInt2, vIttTria) ;
int nRes = FromSpecialToNormal( nResEx) ;
// se punto
if ( nRes == ITTT_VERT || nRes == ITTT_PNT) {
// verifico se punto già inserito
+37 -15
View File
@@ -78,23 +78,30 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
if ( nVertPos2 == 3 || nVertNeg2 == 3)
return ITTT_NO ;
// se i triangoli sono complanari
if ( ( nVertPos1 == 0 && nVertNeg1 == 0) || ( nVertPos2 == 0 && nVertNeg2 == 0))
return IntersCoplanarTriaTria( trTria1, trTria2, vTria) ;
// intersezione tra i piani dei due triangoli
Point3d ptL1 ; Vector3d vtL1 ;
if ( IntersPlanePlane( plTria1, plTria2, ptL1, vtL1) != IPPT_YES)
int nresPP = IntersPlanePlane( plTria1, plTria2, ptL1, vtL1) ;
if ( nresPP == IPPT_NO)
return ITTT_NO ;
// se i triangoli sono complanari
if ( nresPP == IPPT_OVERLAPS)
return IntersCoplanarTriaTria( trTria1, trTria2, vTria) ;
// limito la linea di intersezione con il primo triangolo
int nRes1 = IntersCoplanarLineTria( ptL1, vtL1, 100.0, trTria1, ptInt, ptInt2, false) ;
if ( nRes1 == ILTT_NO)
return ITTT_NO ;
// il segmento calcolato va limitato col secondo triangolo
Point3d ptL2 = ptInt ;
Vector3d vtL2 = ptInt2 - ptInt ;
double dLen = vtL2.Len() ;
vtL2 /= dLen ;
Vector3d vtL2 = vtL1 ;
double dLen = 0 ;
if ( nRes1 != ILTT_VERT) {
vtL2 = ptInt2 - ptInt ;
dLen = vtL2.Len() ;
vtL2 /= dLen ;
}
int nRes2 = IntersCoplanarLineTria( ptL2, vtL2, dLen, trTria2, ptInt, ptInt2, true) ;
return nTriaTriaIntersCases[nRes1][nRes2] ;
@@ -104,14 +111,18 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
int
IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TRIA3DVECTOR& vTria)
{
// determino il piano medio dei due triangoli
Plane3d plMed ;
plMed.Set( ( trTria2.GetCentroid() + trTria2.GetCentroid()) / 2, trTria1.GetN() + trTria2.GetN()) ;
// creo la regione equivalente al primo triangolo
SurfFlatRegion sfrTria1 ;
PtrOwner<CurveComposite> pCcTria1( CreateBasicCurveComposite()) ;
if ( IsNull( pCcTria1))
return ITTT_NO ;
pCcTria1->AddPoint( trTria1.GetP( 0)) ;
pCcTria1->AddLine( trTria1.GetP( 1)) ;
pCcTria1->AddLine( trTria1.GetP( 2)) ;
pCcTria1->AddPoint( ProjectPointOnPlane( trTria1.GetP( 0), plMed)) ;
pCcTria1->AddLine( ProjectPointOnPlane( trTria1.GetP( 1), plMed)) ;
pCcTria1->AddLine( ProjectPointOnPlane( trTria1.GetP( 2), plMed)) ;
pCcTria1->Close() ;
if ( ! sfrTria1.AddExtLoop( Release( pCcTria1)))
return ITTT_NO ;
@@ -121,9 +132,9 @@ IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TR
PtrOwner<CurveComposite> pCcTria2( CreateBasicCurveComposite()) ;
if ( IsNull( pCcTria2))
return ITTT_NO ;
pCcTria2->AddPoint( trTria2.GetP( 0)) ;
pCcTria2->AddLine( trTria2.GetP( 1)) ;
pCcTria2->AddLine( trTria2.GetP( 2)) ;
pCcTria2->AddPoint( ProjectPointOnPlane( trTria2.GetP( 0), plMed)) ;
pCcTria2->AddLine( ProjectPointOnPlane( trTria2.GetP( 1), plMed)) ;
pCcTria2->AddLine( ProjectPointOnPlane( trTria2.GetP( 2), plMed)) ;
pCcTria2->Close() ;
if ( ! sfrTria2.AddExtLoop( Release( pCcTria2)))
return ITTT_NO ;
@@ -136,8 +147,19 @@ IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TR
// recupero il contorno esterno del risultato come polilinea
PolyLine PL ;
if ( ! sfrTria1.ApproxLoopWithLines( 0, 0, LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
PtrOwner<ICurve> pLoop( sfrTria1.GetLoop( 0, 0)) ;
if ( IsNull( pLoop) || pLoop->GetType() != CRV_COMPO)
return ITTT_NO ;
ICurveComposite* pCoLoop = GetBasicCurveComposite( pLoop) ;
for ( int i = 0 ; i < pCoLoop->GetCurveCount() ; ++ i) {
const ICurve* pCrv = pCoLoop->GetCurve( i) ;
if ( i == 0) {
Point3d ptS ; pCrv->GetStartPoint( ptS) ;
PL.AddUPoint( i, ptS) ;
}
Point3d ptE ; pCrv->GetEndPoint( ptE) ;
PL.AddUPoint( i+1, ptE) ;
}
// eseguo una triangolazione del contorno chiuso
PNTVECTOR vPnt ;
+12 -11
View File
@@ -51,9 +51,9 @@ IntersRectangleTriangle( const Point3d& ptP, const Vector3d& vtL1, const Vector3
Point3d ptIntA1, ptIntA2 ;
TRIA3DVECTOR vTriaA ;
int nIntTypeA = IntersTriaTria( trTria, trTriaA, ptIntA1, ptIntA2, vTriaA) ;
if ( nFromSpecialToNormal[nIntTypeA] == ITTT_PNT || nFromSpecialToNormal[nIntTypeA] == ITTT_VERT)
if ( FromSpecialToNormal( nIntTypeA) == ITTT_PNT || FromSpecialToNormal( nIntTypeA) == ITTT_VERT)
nIntA = 1 ;
else if ( nFromSpecialToNormal[nIntTypeA] == ITTT_YES || nFromSpecialToNormal[nIntTypeA] == ITTT_EDGE) {
else if ( FromSpecialToNormal( nIntTypeA) == ITTT_YES || FromSpecialToNormal( nIntTypeA) == ITTT_EDGE) {
nIntA = 2 ;
}
// Interseco il triangolo con il secondo dei due triangoli del rettangolo
@@ -61,9 +61,9 @@ IntersRectangleTriangle( const Point3d& ptP, const Vector3d& vtL1, const Vector3
Point3d ptIntB1, ptIntB2 ;
TRIA3DVECTOR vTriaB ;
int nIntTypeB = IntersTriaTria( trTria, trTriaB, ptIntB1, ptIntB2, vTriaB) ;
if ( nFromSpecialToNormal[nIntTypeB] == ITTT_PNT || nFromSpecialToNormal[nIntTypeB] == ITTT_VERT)
if ( FromSpecialToNormal( nIntTypeB) == ITTT_PNT || FromSpecialToNormal( nIntTypeB) == ITTT_VERT)
nIntB = 1 ;
else if ( nFromSpecialToNormal[nIntTypeB] == ITTT_YES || nFromSpecialToNormal[nIntTypeB] == ITTT_EDGE) {
else if ( FromSpecialToNormal( nIntTypeB) == ITTT_YES || FromSpecialToNormal( nIntTypeB) == ITTT_EDGE) {
nIntB = 2 ;
}
// Unisco le due intersezioni
@@ -911,8 +911,8 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
if ( m_nStatus != OK || ! SurfB.IsValid())
return false ;
// Unordered map dei segmenti di intersezione
std::unordered_map <int, Chain> LineMapA ;
std::unordered_map <int, Chain> LineMapB ;
unordered_map <int, Chain> LineMapA ;
unordered_map <int, Chain> LineMapB ;
// Ciclo sui triangoli delle mesh
int nTriaNumA = GetTriangleSize() ;
int nTriaNumB = SurfB.GetTriangleSize() ;
@@ -946,12 +946,12 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
Point3d ptSegSt, ptSegEn ;
TRIA3DVECTOR vTria ;
int nIntType = IntersTriaTria( trTriaA, trTriaB, ptSegSt, ptSegEn, vTria) ;
if ( ! ( nFromSpecialToNormal[nIntType] == ITTT_NO ||
nFromSpecialToNormal[nIntType] == ITTT_OVERLAPS ||
nFromSpecialToNormal[nIntType] == ITTTS_VERT_VERT)) {
if ( ! ( FromSpecialToNormal( nIntType) == ITTT_NO ||
FromSpecialToNormal( nIntType) == ITTT_OVERLAPS ||
FromSpecialToNormal( nIntType) == ITTTS_VERT_VERT)) {
// Assegno i dati di intersezione
IntSegment CurInters ;
if ( nFromSpecialToNormal[nIntType] == ITTT_EDGE || nFromSpecialToNormal[nIntType] == ITTT_YES) {
if ( FromSpecialToNormal( nIntType) == ITTT_EDGE || FromSpecialToNormal( nIntType) == ITTT_YES) {
CurInters.ptSt = ptSegSt ;
CurInters.ptEn = ptSegEn ;
CurInters.bDegenerate = false ;
@@ -1035,7 +1035,6 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
}
}
}
// Ritriangolarizzo i triangoli della superficie A
for ( auto it = LineMapA.begin() ; it != LineMapA.end() ; ++ it) {
@@ -1762,6 +1761,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
vInnerLoop.resize( 0) ;
}
}
// Se i triangoli delle superfici non si intersecano, una delle due è totalmente interna o esterna all'altra.
if ( ! bModif) {
int nVertNum = 0 ;
@@ -1848,6 +1848,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
// Se avvenuta modifica, aggiorno tutto
if ( bModif)
bContinue = ( AdjustVertices() && DoCompacting() && SurfB.AdjustVertices() && SurfB.DoCompacting()) ;
// Triangoli sovrapposti
if ( bContinue) {
int nTriaNumA = GetTriangleSize() ;
+40 -29
View File
@@ -611,7 +611,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d&
Mrt_ZMilling( i, ptLs[i], ptLe[i], vtLs[i], vtALs[i]) ;
break ;
case Tool::CHISEL :
Chs_ZMilling( i, ptLs[i], ptLe[i], vtLs[i], vtALs[i]) ;
Chs_Milling( i, ptLs[i], ptLe[i], vtLs[i], vtALs[i]) ;
break ;
}
}
@@ -628,6 +628,10 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d&
break ;
case Tool::CONEMILL :
Conus_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
break ;
case Tool::MORTISER :
Mrt_Milling( i, ptLs[i], ptLe[i], vtLs[i], vtALs[i]) ;
break ;
}
}
}
@@ -697,6 +701,9 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d&
case Tool::CONEMILL :
Conus_XYMilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
break ;
case Tool::MORTISER :
Mrt_Milling( i, ptLs[i], ptLe[i], vtLs[i], vtALs[i]) ;
break ;
}
}
}
@@ -745,9 +752,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d&
Conus_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ;
break ;
case Tool::MORTISER :
// ammesso solo movimento perpendicolare all'asse utensile
if ( dSqLLong < EPS_SMALL * EPS_SMALL)
Mrt_Milling( i, ptLs[i], ptLe[i], vtLs[i], vtALs[i]) ;
Mrt_Milling( i, ptLs[i], ptLe[i], vtLs[i], vtALs[i]) ;
break ;
case Tool::CHISEL :
// ammesso solo movimento perpendicolare all'asse utensile
@@ -1601,12 +1606,10 @@ VolZmap::Mrt_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const
{
// Proiezione della traiettoria sul piano di movimento
Vector3d vtPlV = vtToolDir ^ vtAux ;
if ( vtPlV * ( ptE - ptS) < 0)
vtPlV *= - 1 ;
Point3d ptPlS = ptS ;
Point3d ptPlE = ptS + ( ptE - ptS) * vtPlV * vtPlV ;
Point3d ptPlE = ptS + ( ( ptE - ptS) - ( ptE - ptS) * vtAux * vtAux) ;
// Scompongo la mortasatrice in solidi semplici
@@ -1615,7 +1618,7 @@ VolZmap::Mrt_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const
double dLenY = m_Tool.GetMrtChsThickness() ;
double dLenZ = m_Tool.GetHeigth() - m_Tool.GetCornRadius() ;
CompPar_ZMilling( nGrid, dLenX, dLenY, dLenZ, ptPlS, ptPlE, vtToolDir, vtAux) ;
CompPar_Milling( nGrid, dLenX, dLenY, dLenZ, ptPlS, ptPlE, vtToolDir, vtAux) ;
// Se la punta è di tipo bull-nose
if ( abs( m_Tool.GetMrtChsWidth() - 2 * m_Tool.GetCornRadius()) > EPS_SMALL) {
@@ -1626,12 +1629,15 @@ VolZmap::Mrt_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const
dLenX = abs( m_Tool.GetMrtChsWidth() - 2 * m_Tool.GetCornRadius()) ;
dLenZ = m_Tool.GetCornRadius() ;
// Cilindro ( il moto dei due cilindri si sovrappone, quindi è inutile
CompPar_Milling( nGrid, dLenX, dLenY, dLenZ, ptTipS, ptTipE, vtToolDir, vtAux) ;
// Cilindri ( il moto dei due cilindri non sempre si sovrappone, quindi è fondamentale
// eseguire due volte il conto
Point3d ptSminus = ptTipS - ( 0.5 * dLenX) * vtPlV + 0.5 * dLenY * vtAux ;
Point3d ptEplus = ptTipE + ( 0.5 * dLenX) * vtPlV + 0.5 * dLenY * vtAux ;
CompCyl_Milling( nGrid, ptSminus, ptEplus, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ;
Point3d ptSCyl = ptTipS - ( 0.5 * dLenX) * vtPlV + 0.5 * dLenY * vtAux ;
Point3d ptECyl = ptTipE - ( 0.5 * dLenX) * vtPlV + 0.5 * dLenY * vtAux ;
CompCyl_Milling( nGrid, ptSCyl, ptECyl, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ;
ptSCyl = ptTipS + ( 0.5 * dLenX) * vtPlV + 0.5 * dLenY * vtAux ;
ptECyl = ptTipE + ( 0.5 * dLenX) * vtPlV + 0.5 * dLenY * vtAux ;
CompCyl_Milling( nGrid, ptSCyl, ptECyl, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ;
}
// se la punta è di tipo sfera
@@ -2792,9 +2798,11 @@ bool
VolZmap::Mrt_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux)
{
// Proiezione della traiettoria sul piano dei movimenti possibili
Point3d ptSp = ptS ;
Vector3d vtMoveDir = vtToolDir ^ vtAux ;
Point3d ptEp = ptS + ( ptE - ptS) * vtMoveDir * vtMoveDir ;
Vector3d vtVOnP = vtToolDir ^ vtAux ;
if ( vtVOnP * ( ptE - ptS) < 0)
vtVOnP *= -1 ;
Point3d ptPlS = ptS ;
Point3d ptPlE = ptS + ( ( ptE - ptS) - (ptE - ptS) * vtAux * vtAux) ;
// Scompongo la mortasatrice in solidi semplici
@@ -2803,35 +2811,38 @@ VolZmap::Mrt_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const V
double dLenY = m_Tool.GetMrtChsThickness() ;
double dLenZ = m_Tool.GetHeigth() - m_Tool.GetCornRadius() ;
CompPar_Milling( nGrid, dLenX, dLenY, dLenZ, ptS, ptEp, vtToolDir, vtAux) ;
Point3d ptBasePS = ptPlS - 0.5 * dLenZ * vtToolDir + 0.5 * dLenY * vtAux ;
Point3d ptBasePE = ptPlE - 0.5 * dLenZ * vtToolDir + 0.5 * dLenY * vtAux ;
CompPar_Milling( nGrid, dLenX, dLenZ, dLenY, ptBasePS, ptBasePE, vtAux, vtToolDir) ;
// Se la punta è di tipo bull-nose
if ( abs( m_Tool.GetMrtChsWidth() - 2 * m_Tool.GetCornRadius()) > EPS_SMALL) {
// Parallelepipedo di punta
Point3d ptTipS = ptS - dLenZ * vtToolDir ;
Point3d ptTipE = ptEp - dLenZ * vtToolDir ;
Point3d ptTipPS = ptBasePS - 0.5 * dLenZ * vtToolDir ;
Point3d ptTipPE = ptBasePE - 0.5 * dLenZ * vtToolDir ;
dLenX = abs( m_Tool.GetMrtChsWidth() - 2 * m_Tool.GetCornRadius()) ;
dLenZ = m_Tool.GetCornRadius() ;
Vector3d vtVOnP = vtToolDir ^ vtAux ;
if ( vtVOnP * ( ptTipE - ptTipS) < 0)
vtVOnP *= - 1 ;
ptTipPS -= 0.5 * dLenZ * vtToolDir ;
ptTipPE -= 0.5 * dLenZ * vtToolDir ;
CompPar_Milling( nGrid, dLenX, dLenZ, dLenY, ptTipPS, ptTipPE, vtAux, vtToolDir) ;
// Cilindri
Point3d ptSminus = ptTipS - ( 0.5 * dLenX) * vtVOnP + 0.5 * dLenY * vtAux ;
Point3d ptEminus = ptTipE - ( 0.5 * dLenX) * vtVOnP + 0.5 * dLenY * vtAux ;
Point3d ptSplus = ptTipS + ( 0.5 * dLenX) * vtVOnP + 0.5 * dLenY * vtAux ;
Point3d ptEplus = ptTipE + ( 0.5 * dLenX) * vtVOnP + 0.5 * dLenY * vtAux ;
CompCyl_Milling( nGrid, ptSminus, ptEplus, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ;
Point3d ptSminus = ptTipPS + 0.5 * dLenZ * vtToolDir - ( 0.5 * dLenX) * vtVOnP ;
Point3d ptEminus = ptTipPE + 0.5 * dLenZ * vtToolDir - ( 0.5 * dLenX) * vtVOnP ;
CompCyl_Milling( nGrid, ptSminus, ptEminus, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ;
Point3d ptSplus = ptTipPS + 0.5 * dLenZ * vtToolDir + ( 0.5 * dLenX) * vtVOnP ;
Point3d ptEplus = ptTipPE + 0.5 * dLenZ * vtToolDir + ( 0.5 * dLenX) * vtVOnP ;
CompCyl_Milling( nGrid, ptSplus, ptEplus, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ;
}
// se la punta è di tipo sfera
else {
// Cilindro
Point3d ptCylS = ptS - dLenZ * vtToolDir + 0.5 * dLenY * vtAux ;
Point3d ptCylE = ptEp - dLenZ * vtToolDir + 0.5 * dLenY * vtAux ;
Point3d ptCylS = ptBasePS - 0.5 * dLenZ * vtToolDir ;
Point3d ptCylE = ptBasePE - 0.5 * dLenZ * vtToolDir ;
CompCyl_Milling( nGrid, ptCylS, ptCylE, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ;
}