From f13661c0bdbb16daeffdcc296bf61e96e164ced1 Mon Sep 17 00:00:00 2001 From: LorenzoM Date: Wed, 12 May 2021 18:03:16 +0200 Subject: [PATCH] Divisione di rettangoli lunghi --- SurfTriMeshBooleans.cpp | 184 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 171 insertions(+), 13 deletions(-) diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index f33ec6c..d63bace 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -4076,7 +4076,168 @@ SurfTriMesh::EdgeEdgeContactManager( const SurfTriMesh& OthSurf, return true ; } -// Prova +//---------------------------------------------------------------------------- +bool +RegularizeRectangleSurf( SurfTriMesh& Surf) +{ + // Se la superficie non è un quadrilatero, non procedo. + int nNumVert = Surf.GetVertexCount() ; + if ( nNumVert != 4 || Surf.GetFacetCount() != 1) + return true ; + // Recupero il contorno. + POLYLINEVECTOR ContourVec ; + Surf.GetFacetLoops( 0, ContourVec) ; + // Recupero i vertici. + Point3d ptV[4] ; + int nIndex = 0 ; + bool bContinue = ContourVec[0].GetFirstPoint( ptV[nIndex]) ; + while ( bContinue) { + ++ nIndex ; + bContinue = nIndex < 4 && ContourVec[0].GetNextPoint( ptV[nIndex]) ; + } + // Se la superficie non è un rettangolo lungo, non procedo. + Vector3d vtV[2] ; + vtV[0] = ptV[1] - ptV[0] ; + vtV[1] = ptV[2] - ptV[1] ; + double dLen[2] = { vtV[0].Len(), vtV[1].Len() } ; + int nMin = dLen[0] < dLen[1] ? 0 : 1 ; + if ( abs( vtV[0] * vtV[1]) > EPS_SMALL || dLen[nMin] / dLen[( nMin + 1) % 2] > 0.25) + return true ; + // Ridefinisco il contrno del rettangolo. + Point3d ptNewV[12] ; + int nVV = 0 ; + for ( int nV = 0 ; nV < 4 ; ++ nV) { + ptNewV[nVV] = ptV[nV] ; + if ( nV != nMin && nV != ( nMin + 2) % 4) { + ++ nVV ; + ptNewV[nVV] = ( 4 * ptV[nV] + ptV[( nV + 1) % 4]) / 5 ; + ++ nVV ; + ptNewV[nVV] = ( 3 * ptV[nV] + 2 * ptV[( nV + 1) % 4]) / 5 ; + ++ nVV ; + ptNewV[nVV] = ( 2 * ptV[nV] + 3 * ptV[( nV + 1) % 4]) / 5 ; + ++ nVV ; + ptNewV[nVV] = ( ptV[nV] + 4 * ptV[( nV + 1) % 4]) / 5 ; + } + ++ nVV ; + } + // Ridefinisco la superficie. + SurfTriMesh NewSurf ; + NewSurf.CopyFrom( &Surf) ; + NewSurf.Clear() ; + if ( nMin == 0) { + int nNewId[3] ; + nNewId[0] = NewSurf.AddVertex( ptNewV[0]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[1]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[2]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[0]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[2]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[11]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[11]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[2]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[3]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[11]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[3]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[10]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[10]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[3]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[4]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[10]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[4]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[9]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[9]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[4]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[5]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[9]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[5]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[8]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[8]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[5]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[6]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[8]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[6]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[7]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + } + else { + int nNewId[3] ; + nNewId[0] = NewSurf.AddVertex( ptNewV[0]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[1]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[10]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[0]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[10]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[11]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[1]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[2]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[9]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[1]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[9]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[10]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[2]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[3]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[8]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[2]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[8]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[9]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[3]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[4]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[7]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[3]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[7]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[8]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[4]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[5]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[6]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + nNewId[0] = NewSurf.AddVertex( ptNewV[4]) ; + nNewId[1] = NewSurf.AddVertex( ptNewV[6]) ; + nNewId[2] = NewSurf.AddVertex( ptNewV[7]) ; + if ( ! IsValidSvt( NewSurf.AddTriangle( nNewId))) + return false ; + } + + if ( NewSurf.AdjustTopology() && NewSurf.DoCompacting()) { + Surf.CopyFrom( &NewSurf) ; + return true ; + } + return false ; +} + //---------------------------------------------------------------------------- bool SplitPolyLineContour( const POLYLINEVECTOR& vContourVec, POLYLINEVECTOR& vContourVec1, POLYLINEVECTOR& vContourVec2) @@ -4406,6 +4567,7 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) nTime = 0; //////////////////////////////////////////////////////////////////////////////////////////////////////// SurfTriMesh& SurfB = Other ; + RegularizeRectangleSurf( SurfB) ; // Le superfici devono essere valide if ( m_nStatus != OK || ! SurfB.IsValid()) return false ; @@ -4756,7 +4918,7 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) frIntersRegion.GetArea( dIntersRegArea) ; // Assegno indice di parte ai pezzi. if ( dIntersRegArea > EPS_SMALL) { - bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; // RegionA.GetNormVersor()* RegionB.GetNormVersor() > 0; + bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; int nPartIndex = bCodirectedNorm ? 2 : - 2 ; itFacetA->second[nPieceNumA].nPiecePart = nPartIndex ; itFacetB->second[nPieceNumB].nPiecePart = nPartIndex ; @@ -4784,7 +4946,7 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) frIntersRegion.GetArea( dIntersRegArea) ; // Assegno indice di parte ai pezzi. if ( dIntersRegArea > EPS_SMALL) { - bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; //RegionA.GetNormVersor() * RegionB.GetNormVersor() > 0 ; + bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; int nPartIndex = bCodirectedNorm ? 2 : - 2 ; itFacetA->second[nPieceNumA].nPiecePart = nPartIndex ; itFacetB->second[nPieceNumB].nPiecePart = nPartIndex ; @@ -4818,7 +4980,7 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) frIntersRegion.GetArea( dIntersRegArea) ; // Assegno indice di parte al pezzo di faccia A e ai triangoli della faccia B. if ( dIntersRegArea > EPS_SMALL) { - bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; //RegionA.GetNormVersor() * RegionB.GetNormVersor() > 0 ; + bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; int nPartIndex = bCodirectedNorm ? 2 : - 2 ; itFacetA->second[nPieceNumA].nPiecePart = nPartIndex ; INTVECTOR vTB ; @@ -4849,7 +5011,7 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) frIntersRegion.GetArea( dIntersRegArea) ; // Assegno indice di parte al pezzo di faccia A e ai triangoli della faccia B. if ( dIntersRegArea > EPS_SMALL) { - bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; //RegionA.GetNormVersor() * RegionB.GetNormVersor() > 0 ; + bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; int nPartIndex = bCodirectedNorm ? 2 : - 2 ; itFacetA->second[nPieceNumA].nPiecePart = nPartIndex ; INTVECTOR vTB ; @@ -4897,10 +5059,6 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) auto itFacetB = NewFacetB.find( nFB) ; // Faccia B divisa in pezzi if ( itFacetB != NewFacetB.end()) { - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (nFB == 1) - int a = 0; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// for ( int nPieceNumB = 0 ; nPieceNumB < int( itFacetB->second.size()) ; ++ nPieceNumB) { POLYLINEVECTOR& vPieceLoopsVecB = itFacetB->second[nPieceNumB].vPieceLoop ; PtrOwner pRegB( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( vPieceLoopsVecB))) ; @@ -4922,7 +5080,7 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) frIntersRegion.GetArea( dIntersRegArea) ; // Assegno indice di parte ai triangoli di A e ai pezzi di B. if ( dIntersRegArea > EPS_SMALL) { - bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; //RegionA.GetNormVersor() * RegionB.GetNormVersor() > 0 ; + bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; int nPartIndex = bCodirectedNorm ? 2 : - 2 ; INTVECTOR vTA ; GetAllTriaInFacet( nFA, vTA) ; @@ -4953,7 +5111,7 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) frIntersRegion.GetArea( dIntersRegArea) ; // Assegno indice di parte ai triangoli di A e ai pezzi di B. if ( dIntersRegArea > EPS_SMALL) { - bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; //RegionA.GetNormVersor() * RegionB.GetNormVersor() > 0 ; + bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; int nPartIndex = bCodirectedNorm ? 2 : - 2 ; INTVECTOR vTA ; GetAllTriaInFacet( nFA, vTA) ; @@ -4990,7 +5148,7 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) frIntersRegion.GetArea( dIntersRegArea) ; // Assegno indice di parte al pezzo di faccia A e ai triangoli della faccia B. if ( dIntersRegArea > EPS_SMALL) { - bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; //RegionA.GetNormVersor() * RegionB.GetNormVersor() > 0 ; + bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; int nPartIndex = bCodirectedNorm ? 2 : - 2 ; INTVECTOR vTA ; GetAllTriaInFacet( nFA, vTA) ; @@ -5024,7 +5182,7 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) frIntersRegion.GetArea( dIntersRegArea) ; // Assegno indice di parte al pezzo di faccia A e ai triangoli della faccia B. if ( dIntersRegArea > EPS_SMALL) { - bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; //RegionA.GetNormVersor() * RegionB.GetNormVersor() > 0 ; + bool bCodirectedNorm = plPlaneA.GetVersN() * plPlaneB.GetVersN() > 0 ; int nPartIndex = bCodirectedNorm ? 2 : - 2 ; INTVECTOR vTA ; GetAllTriaInFacet( nFA, vTA) ;