From c93adf402b70db28d855a5371a56904be5a7191c Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Tue, 28 May 2019 15:31:16 +0000 Subject: [PATCH] EgtGeomKernel 2.1e5 : - aggiunta funzione SurfTriMesh::GeneralizedCut per taglio TriMesh con curva che rappresenta sezione di cilindro infinito. --- EgtGeomKernel.rc | Bin 11710 -> 11710 bytes EgtGeomKernel.vcxproj | 1 + EgtGeomKernel.vcxproj.filters | 3 + GdbExecutor.cpp | 20 + GdbExecutor.h | 1 + SurfTriMesh.h | 1 + SurfTriMeshBooleans.cpp | 911 ++++++++++++++++++++++++++++++++++ 7 files changed, 937 insertions(+) create mode 100644 SurfTriMeshBooleans.cpp diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index a2b68f171bc288616cc392cfe1287dea06fc9570..995ffe51427a941224768c2c47ec68ceb6ef6f9f 100644 GIT binary patch delta 94 zcmdlNy)SyhFE&Qg&A-_cnHfzdD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-X4V@L delta 94 zcmdlNy)SyhFE&P#&A-_cnHfzcD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-WjGrO diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 1678055..530478d 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -353,6 +353,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index f693099..18b6aa7 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -393,6 +393,9 @@ File di origine\GeoDist + + File di origine\Geo + diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index f07f073..fddac5b 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -2174,6 +2174,9 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams) else if ( sCmd2 == "CLONEPART") { return SurfTrimeshClonePart( vsParams) ; } + else if ( sCmd2 == "GENCUT") { + return SurfTrimeshGenCut( vsParams) ; + } else return false ; } @@ -2649,6 +2652,23 @@ GdbExecutor::SurfTrimeshClonePart( const STRVECTOR& vsParams) return AddGeoObj(vsParams[0], vsParams[2], Release( pNewSurf)) ; } +//---------------------------------------------------------------------------- +bool +GdbExecutor::SurfTrimeshGenCut( const STRVECTOR& vsParams) +{ + // Parametri: nSurfId, nCvId + if ( vsParams.size() != 2) + return false ; + // Recupero Id superficie + int nIdSurf = GetIdParam( vsParams[0]) ; + ISurfTriMesh* pStmM = GetSurfTriMesh( m_pGDB->GetGeoObj( nIdSurf)) ; + SurfTriMesh* pStmF = static_cast ( pStmM) ; + // Recupero Id curva + int nIdCurve = GetIdParam( vsParams[1]) ; + ICurve* pCurve = GetCurve( m_pGDB->GetGeoObj( nIdCurve)) ; + return pStmF->GeneralizedCut( *pCurve, true) ; +} + //---------------------------------------------------------------------------- bool GdbExecutor::ExecuteVolZmap( const string& sCmd2, const STRVECTOR& vsParams) diff --git a/GdbExecutor.h b/GdbExecutor.h index 98f03c8..65f3073 100644 --- a/GdbExecutor.h +++ b/GdbExecutor.h @@ -117,6 +117,7 @@ class GdbExecutor : public IGdbExecutor bool SurfTrimeshCheckConnection( const STRVECTOR& vsParams) ; bool SurfTrimeshRemovePart( const STRVECTOR& vsParams) ; bool SurfTrimeshClonePart( const STRVECTOR& vsParams) ; + bool SurfTrimeshGenCut( const STRVECTOR& vsParams) ; bool ExecuteVolZmap( const std::string& sCmd2, const STRVECTOR& vsParams) ; //bool VolZmapCreate( const STRVECTOR& vsParams) ; //bool VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams) ; diff --git a/SurfTriMesh.h b/SurfTriMesh.h index 10f510f..0c85808 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -185,6 +185,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool GetFacetsContact( int nF1, int nF2, bool& bAdjac, Point3d& ptP1, Point3d& ptP2, double& dAng) const override ; SurfTriMesh* CloneFacet( int nF) const override ; bool Cut( const Plane3d& plPlane, bool bSaveOnEq) override ; + bool GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq) override ; bool GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const override ; const BBox3d& GetAllTriaBox( void) const override ; int GetPartCount( void) const override ; diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp new file mode 100644 index 0000000..c3f97eb --- /dev/null +++ b/SurfTriMeshBooleans.cpp @@ -0,0 +1,911 @@ +//---------------------------------------------------------------------------- +// EgalTech 2019-2019 +//---------------------------------------------------------------------------- +// File : SurfTriMeshBooleans.cpp Data : 27.05.19 Versione : 2.1e5 +// Contenuto : Implementazione delle funzioni booleane per SurfFTrimesh. +// +// +// +// Modifiche : 10.05.19 LM Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#include "stdafx.h" +#include "SurfTriMesh.h" +#include "CurveLine.h" +#include "CurveComposite.h" +#include "SurfFlatRegion.h" +#include "DistPointLine.h" +#include "Triangulate.h" +#include "GeoConst.h" +#include "/EgtDev/Include/EgkCurve.h" +#include "/EgtDev/Include/EgkDistPointCurve.h" +#include "/EgtDev/Include/EgkIntersLineTria.h" +#include "/EgtDev/Include/EgkIntersTriaTria.h" +#include "/EgtDev/Include/EGkChainCurves.h" +#include + +//---------------------------------------------------------------------------- +struct TriaInOut { + Triangle3d trTria ; + bool bTriaInside ; +} ; + +//---------------------------------------------------------------------------- +bool +FindRectangleTriangleIntersectionSegment(const Point3d ptP1, const Point3d ptP2, const Point3d ptP3, const Point3d ptP4, + const Triangle3d& trTria, Point3d& ptStSeg, Point3d& ptEnSeg) +{ + // Definisco i due triangoli formanti il rettangolo + Triangle3d trTria1, trTria2 ; + trTria1.Set( ptP1, ptP2, ptP4) ; + trTria2.Set( ptP2, ptP3, ptP4) ; + trTria1.Validate() ; + trTria2.Validate() ; + Vector3d vtSeg = ptP2 - ptP1 ; + vtSeg.Normalize() ; + // Interseco il triangolo corrente col primo dei due triangoli del rettangolo + Point3d ptIntA1, ptIntB1 ; + TRIA3DVECTOR vTria1 ; + int nIntType1 = IntersTriaTria( trTria1, trTria, ptIntA1, ptIntB1, vTria1) ; + if ( nIntType1 == ITTT_YES) { + if ( ( ptIntB1 - ptIntA1) * vtSeg < 0.) + std::swap( ptIntA1, ptIntB1) ; + ptStSeg = ptIntA1 ; + ptEnSeg = ptIntB1 ; + } + // Interseco il triangolo corrente con il secondo dei due triangoli del rettangolo + Point3d ptIntA2, ptIntB2 ; + TRIA3DVECTOR vTria2 ; + int nIntType2 = IntersTriaTria( trTria2, trTria, ptIntA2, ptIntB2, vTria2) ; + if ( nIntType2 == ITTT_YES) { + if ( ( ptIntB2 - ptIntA2) * vtSeg < 0.) + std::swap( ptIntA2, ptIntB2) ; + ptEnSeg = ptIntB2 ; + if ( ! ( nIntType1 == ITTT_YES)) + ptStSeg = ptIntA2 ; + } + return ( nIntType1 == ITTT_YES || nIntType2 == ITTT_YES) ; +} + +//---------------------------------------------------------------------------- +bool +FindRectangleTriangleIntersectionSegment2( const Point3d ptP1, const Point3d ptP2, const Point3d ptP3, const Point3d ptP4, + const Triangle3d& trTria, Point3d& ptStSeg, Point3d& ptEnSeg) +{ + // Definisco i due triangoli formanti il rettangolo + Triangle3d trTria1, trTria2; + trTria1.Set(ptP1, ptP2, ptP4); + trTria2.Set(ptP2, ptP3, ptP4); + trTria1.Validate(); + trTria2.Validate(); + Vector3d vtSeg = ptP3 - ptP1; + vtSeg.Normalize(); + // Interseco il triangolo corrente col primo dei due triangoli del rettangolo + Point3d ptIntA1, ptIntB1; + TRIA3DVECTOR vTria1; + int nIntType1 = IntersTriaTria(trTria1, trTria, ptIntA1, ptIntB1, vTria1); + if ( nIntType1 == ITTT_YES) { + if ((ptIntB1 - ptIntA1) * vtSeg < 0.) + std::swap(ptIntA1, ptIntB1); + ptStSeg = ptIntA1; + ptEnSeg = ptIntB1; + } + // Interseco il triangolo corrente con il secondo dei due triangoli del rettangolo + Point3d ptIntA2, ptIntB2; + TRIA3DVECTOR vTria2; + int nIntType2 = IntersTriaTria(trTria2, trTria, ptIntA2, ptIntB2, vTria2); + if ( nIntType2 == ITTT_YES) { + if ((ptIntB2 - ptIntA2) * vtSeg < 0.) + std::swap(ptIntA2, ptIntB2); + ptEnSeg = ptIntB2; + if ( !( nIntType1 == ITTT_YES)) + ptStSeg = ptIntA2; + } + return ( nIntType1 == ITTT_YES || nIntType2 == ITTT_YES); +} + +//---------------------------------------------------------------------------- +bool +SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq) +{ + // La superficie deve essere valida + if ( m_nStatus != OK) + return false ; + // La curva deve essere valida e chiusa; il vettore estrusione deve essere non nullo + Vector3d vtExtr ; + if ( ( ! cvCurve.GetExtrusion( vtExtr)) || ( ! cvCurve.IsClosed()) || vtExtr.IsSmall()) + return false ; + // Approssimo la curva con segmenti + PolyLine plLine ; + cvCurve.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_STD, plLine) ; + // Appiattisco la polilinea nel piano perpendicolare all'estrusione + Frame3d frCurve ; + Point3d ptStart ; cvCurve.GetStartPoint( ptStart) ; + frCurve.Set( ptStart, vtExtr) ; + plLine.ToLoc( frCurve) ; + plLine.Flatten() ; + double dArea ; + plLine.GetAreaXY( dArea) ; + BBox3d b3Crv ; + plLine.GetLocalBBox( b3Crv) ; + plLine.ToGlob( frCurve) ; + // Assegno il senso di rotazione della curva (visto dalla punta del vettore estrusione) + bool bCCW = ( dArea > 0) ; + // Recupero Bounding-box della trimesh + BBox3d b3SurfBox ; + GetLocalBBox( b3SurfBox) ; + // Trovo minima e massima distanza dei vertici del bounding-box della TriMesh dal piano della curva + b3SurfBox.ToLoc( frCurve) ; + Point3d ptMin, ptMax ; + b3SurfBox.GetMinMax( ptMin, ptMax) ; + Vector3d vtMax = ( ptMax.z + 10) * vtExtr ; + Vector3d vtMin = ( ptMin.z - 10) * vtExtr ; + // Ciclo sui triangoli + bool bModif = false ; + int nNumTria = GetTriangleSize() ; + for ( int nT = 0 ; nT < nNumTria ; ++ nT) { + // Recupero il triangolo + Triangle3d trTria ; + GetTriangle( nT, trTria) ; + // Box del triangolo nel riferimento locale della curva + BBox3d b3Tria ; + trTria.GetLocalBBox( b3Tria) ; + b3Tria.ToLoc( frCurve) ; + // Se il box del triangolo non interseca quello della curva + if ( ! b3Crv.OverlapsXY( b3Tria)) { + if ( bCCW) { + RemoveTriangle( nT) ; + bModif = true ; + } + continue ; + } + // Determino il numero di vertici che cadono nella curva + int nVertInside = 0 ; + // Ciclo sui vertici del triangolo + for ( int nV = 0 ; nV < 3 ; ++ nV) { + // Vertice del triangolo e sua proiezione sul piano della curva + Point3d ptVert ; + if ( ! GetVertex( m_vTria[nT].nIdVert[nV], ptVert)) + continue ; + double dDistVertPlane = ( ptVert - ptStart) * vtExtr ; + Point3d ptVertOnPlane = ptVert - dDistVertPlane * vtExtr ; + // Ciclo sui segmenti della curva, per determinare se la proiezione sulla curva di almeno un vertice + // del triangolo è all'interno del loop oppure un punto della curva, spostandosi lungo una + // retta parallela al versore di estrusione, interseca il triangolo. + double dSqDistVertCurve = DBL_MAX ; + Point3d ptStMin, ptEnMin ; + Point3d ptSt, ptEn ; + bool bContinue = plLine.GetFirstLine( ptSt, ptEn) ; + while ( bContinue) { + CurveLine cvLine ; + cvLine.Set( ptSt, ptEn) ; + // Calcolo della distanza del vertice proiettato sul piano della curva + // dal segmento corrente + DistPointLine dCurDistCalc( ptVertOnPlane, cvLine) ; + double dCurSqDist ; + // Se tale distanza è minore della minima distanza attuale, la aggiorno insieme con gli estremi + // del segmento a distanza minima + if ( dCurDistCalc.GetSqDist( dCurSqDist) && dCurSqDist < dSqDistVertCurve) { + dSqDistVertCurve = dCurSqDist ; + ptStMin = ptSt ; + ptEnMin = ptEn ; + } + bContinue = plLine.GetNextLine( ptSt, ptEn) ; + } + // Direzione del segmento a minima distanza dal vertice corrente proiettato sul piano della curva + Vector3d vtTan = ptEnMin - ptStMin ; + vtTan.Normalize() ; + // Se punto proiettato nella curva aumentiamo il numero di punti interni + if ( ( ptVertOnPlane - ptStMin) * ( vtTan ^ vtExtr) < EPS_SMALL) + ++ nVertInside ; + } + + // Casi in cui l'orientamento della curva stabilisce la parti interne ed esterne del triangolo + if ( abs( trTria.GetN() * vtExtr) > EPS_ZERO) { + // Vettore di segmenti + std::vector vLine ; + // Ciclo sui segmenti + Point3d ptSt, ptEn ; + bool bContinue = plLine.GetFirstLine( ptSt, ptEn) ; + while ( bContinue) { + Point3d ptSegSt, ptSegEn ; + // C'è interferenza fra il rettangolo, ottenuto dall'estrusione del segmento corrente, e il triangolo + if ( FindRectangleTriangleIntersectionSegment( ptSt + vtMin, ptEn + vtMin, ptEn + vtMax, ptSt + vtMax, + trTria, ptSegSt, ptSegEn)) { + // Costruisco il tratto di curva + CurveLine cvLine ; + if ( cvLine.Set( ptSegSt, ptSegEn)) + vLine.emplace_back( cvLine) ; + } + bContinue = plLine.GetNextLine( ptSt, ptEn) ; + } + // Creo i loop + ChainCurves LoopCreator ; + LoopCreator.Init( false, EPS_SMALL, int( vLine.size())) ; + // Carico le curve per concatenarle + for ( int nCv = 0 ; nCv < int( vLine.size()) ; ++ nCv) { + Point3d ptSt = vLine[nCv].GetStart() ; + Point3d ptEn = vLine[nCv].GetEnd() ; + Vector3d vtDir; vLine[nCv].GetStartDir( vtDir) ; + LoopCreator.AddCurve( nCv + 1, ptSt, vtDir, ptEn, vtDir) ; + } + // Recupero i concatenamenti + INTVECTOR vIds ; + Point3d ptNearStart ; + std::vector cvLoopVec ; + while ( LoopCreator.GetChainFromNear( ptNearStart, false, vIds)) { + CurveComposite cvLoop ; + for ( auto i : vIds) { + // Aggiungo la linea alla curva composta. + if ( ! cvLoop.AddCurve( vLine[i - 1], true, 10 * EPS_SMALL)) + return false ; + } + cvLoop.MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG) ; + cvLoopVec.emplace_back( cvLoop) ; + } + + // Fra i loop trovati separo gli aperti dai chiusi + std::vector cvInnerClosedLoopVec ; + std::vector cvOpenLoopVec ; + for ( int nL = 0 ; nL < int( cvLoopVec.size()) ; ++ nL) { + if ( cvLoopVec[nL].IsClosed()) + cvInnerClosedLoopVec.emplace_back( cvLoopVec[nL]) ; + else + cvOpenLoopVec.emplace_back( cvLoopVec[nL]) ; + } + + // Se contemporaneamente c'è almeno un loop chiuso e almeno uno aperto, + // oppure c'è più di un loop chiuso, vi è un errore. + if ( ( cvInnerClosedLoopVec.size() > 0 && cvOpenLoopVec.size() > 0.) || + cvInnerClosedLoopVec.size() > 1) + return false ; + // Se c'è un loop chiuso + if ( cvInnerClosedLoopVec.size() == 1) { + // Passo da curva composita a PolyLine + PolyLine plInnerLoop ; + const ICurve* pCv = cvInnerClosedLoopVec[0].GetFirstCurve() ; + while ( pCv != nullptr) { + // Estremi del segmento corrente del loop chiuso corrente + Point3d ptSegSt, ptSegEn ; + pCv->GetStartPoint( ptSegSt) ; + pCv->GetEndPoint( ptSegEn) ; + plInnerLoop.AddUPoint( 0., ptSegSt) ; + plInnerLoop.AddUPoint( 0., ptSegEn) ; + pCv = cvInnerClosedLoopVec[0].GetNextCurve() ; + } + // Se necessario inverto il loop trovato + if ( trTria.GetN() * vtExtr < - EPS_ZERO) + plInnerLoop.Invert() ; + // Tre vertici dentro la curva + if ( nVertInside == 3) { + // Accedo agli indici del triangolo + int nTriaVertId[3] ; + GetTriangle( nT, nTriaVertId) ; + PolyLine plExternalLoop ; + Point3d ptTriaVert0, ptTriaVert1, ptTriaVert2 ; + GetVertex( nTriaVertId[0], ptTriaVert0) ; + GetVertex( nTriaVertId[1], ptTriaVert1) ; + GetVertex( nTriaVertId[2], ptTriaVert2) ; + // Rimuovo il triangolo corrente + RemoveTriangle( nT) ; + plExternalLoop.AddUPoint( 0., ptTriaVert0) ; + plExternalLoop.AddUPoint( 0., ptTriaVert1) ; + plExternalLoop.AddUPoint( 0., ptTriaVert2) ; + plExternalLoop.AddUPoint( 0., ptTriaVert0) ; + // Poligonalizzo il loop + Triangulate CreateTriangulation ; + PNTVECTOR vPt ; + INTVECTOR vTr ; + POLYLINEVECTOR vPL ; + vPL.emplace_back( plExternalLoop) ; + vPL.emplace_back( plInnerLoop) ; + CreateTriangulation.Make( vPL, vPt, vTr) ; + // Aggiungo i triangoli + for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { + int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2] } ; + int nNewId[3] = { AddVertex( vPt[nNewTriaVertId[0]]), + AddVertex( vPt[nNewTriaVertId[1]]), + AddVertex( vPt[nNewTriaVertId[2]]) } ; + AddTriangle( nNewId) ; + bModif = true ; + } + } + // Se nessun vertice dentro (Con un loop chiuso o ci sono tre vertici dentro alla curva o nessuno) + else { + // Rimuovo il triangolo corrente + RemoveTriangle( nT) ; + // Poligonalizzo il loop + Triangulate CreateTriangulation ; + PNTVECTOR vPt ; + INTVECTOR vTr ; + CreateTriangulation.Make( plInnerLoop, vPt, vTr) ; + // Aggiungo i triangoli + for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { + int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2] } ; + int nNewId[3] = { AddVertex(vPt[nNewTriaVertId[0]]), + AddVertex(vPt[nNewTriaVertId[1]]), + AddVertex(vPt[nNewTriaVertId[2]]) } ; + AddTriangle( nNewId) ; + bModif = true ; + } + } + } + // Loop aperti, devo chiuderli + else if ( cvOpenLoopVec.size() > 0) { + // Creo il loop chiuso padre di tutti, il perimetro del triangolo. + // Questo viene diviso in sotto-loop chiusi mediante quelli aperti. + // I loop chiusi trovati precedentemente sono interni a uno dei sotto-loop + // chiusi di cui è formato il perimetro. + std::vector cvBoundClosedLoopVec ; + CurveComposite cvFirstLoop ; + CurveLine cvEdge ; + cvEdge.Set( trTria.GetP( 0), trTria.GetP( 1)) ; + cvFirstLoop.AddCurve( cvEdge, true, 10 * EPS_SMALL) ; + cvEdge.Set( trTria.GetP( 1), trTria.GetP( 2)) ; + cvFirstLoop.AddCurve( cvEdge, true, 10 * EPS_SMALL) ; + cvEdge.Set( trTria.GetP( 2), trTria.GetP( 0)) ; + cvFirstLoop.AddCurve( cvEdge, true, 10 * EPS_SMALL) ; + cvBoundClosedLoopVec.emplace_back( cvFirstLoop) ; + std::vector vbInOut ; + vbInOut.push_back( true) ; + // Divido il loop di partenza in sotto-loop + while ( cvOpenLoopVec.size() > 0) { + int nLastOpenLoopN = int( cvOpenLoopVec.size()) - 1 ; + for ( int nL = 0 ; nL < int( cvBoundClosedLoopVec.size()) ; ++ nL) { + // Estremi del loop aperto + Point3d ptOpenLoopStP, ptOpenLoopEnP ; + cvOpenLoopVec[nLastOpenLoopN].GetStartPoint( ptOpenLoopStP) ; + cvOpenLoopVec[nLastOpenLoopN].GetEndPoint( ptOpenLoopEnP) ; + // Cerco se esistono dei tratti del loop chiuso corrente che sono + // toccati dagli estremi del loop aperto corrente + const ICurve* pCvSt = nullptr ; + const ICurve* pCvEn = nullptr ; + const ICurve* pCv = cvBoundClosedLoopVec[nL].GetFirstCurve() ; + while ( pCv != nullptr && ( pCvSt == nullptr || pCvEn == nullptr)) { + // Estremi del segmento corrente del loop chiuso corrente + Point3d ptSegSt, ptSegEn ; + pCv->GetStartPoint( ptSegSt) ; + pCv->GetEndPoint( ptSegEn) ; + // Vedo se gli estremi del loop aperto stanno su un segmento del chiuso + DistPointLine dStDistCalc( ptOpenLoopStP, ptSegSt, ptSegEn) ; + DistPointLine dEnDistCalc( ptOpenLoopEnP, ptSegSt, ptSegEn) ; + double dSqDistSt ; + dStDistCalc.GetSqDist( dSqDistSt) ; + if ( SqDist( ptOpenLoopStP, ptSegSt) < EPS_SMALL * EPS_SMALL || + SqDist( ptOpenLoopStP, ptSegEn) < EPS_SMALL * EPS_SMALL) + dSqDistSt = 1. ; + if ( dSqDistSt < EPS_SMALL * EPS_SMALL) + pCvSt = pCv ; + double dSqDistEn ; + dEnDistCalc.GetSqDist( dSqDistEn) ; + if ( SqDist( ptOpenLoopEnP, ptSegSt) < EPS_SMALL * EPS_SMALL || + SqDist( ptOpenLoopEnP, ptSegEn) < EPS_SMALL * EPS_SMALL) + dSqDistEn = 1. ; + if ( dSqDistEn < EPS_SMALL * EPS_SMALL) + pCvEn = pCv ; + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + } + // Se entrambi gli estremi del loop aperto sono su un segmento del loop chiuso devo dividere il loop in due + if ( pCvSt != nullptr && pCvEn != nullptr) { + // Entrambi gli estremi del loop aperto sono su uno stesso segmento del loop chiuso + if ( pCvSt == pCvEn) { + bool bFirstInside ; + bool bFirstSt ; + CurveComposite cvSplitLoop1, cvSplitLoop2 ; + // Creo primo loop + pCv = cvBoundClosedLoopVec[nL].GetFirstCurve() ; + while ( pCv != nullptr) { + // Segmenti loop chiuso + if ( pCv != pCvSt && pCv != pCvEn) { + Point3d ptSegSt, ptSegEn ; + pCv->GetStartPoint( ptSegSt) ; + pCv->GetEndPoint( ptSegEn) ; + CurveLine cvSeg ; + cvSeg.Set( ptSegSt, ptSegEn) ; + cvSplitLoop1.AddCurve( cvSeg) ; + } + // Dal chiuso all'aperto + else if ( pCv == pCvSt) { + // Distanze degli estremi del loop aperto dal punto iniziale del segmento corrente + Point3d ptSegSt, ptSegEn ; + pCv->GetStartPoint( ptSegSt) ; + double dDistStSt = SqDist( ptSegSt, ptOpenLoopStP) ; + double dDistStEn = SqDist( ptSegSt, ptOpenLoopEnP) ; + // Devo percorrere il loop aperto nel suo verso + if ( dDistStSt < dDistStEn) { + // Dall'inizio del segmento corrente fino all'inizio del loop aperto + ptSegEn = ptOpenLoopStP ; + CurveLine cvSeg ; + cvSeg.Set( ptSegSt, ptSegEn) ; + cvSplitLoop1.AddCurve( cvSeg) ; + // Loop aperto + const ICurve* pOpenStart = cvOpenLoopVec[nLastOpenLoopN].GetFirstCurve() ; + const ICurve* pOpen = pOpenStart ; + while ( pOpen != nullptr) { + Point3d ptOpenSt, ptOpenEn ; + pOpen->GetStartPoint( ptOpenSt) ; + pOpen->GetEndPoint( ptOpenEn) ; + CurveLine cvOpenSeg ; + cvOpenSeg.Set( ptOpenSt, ptOpenEn) ; + cvSplitLoop1.AddCurve( cvOpenSeg) ; + if ( pOpen == pOpenStart) { + Vector3d vtLast = ptSegSt - ptSegEn ; + vtLast.Normalize() ; + Vector3d vtFirst = ptOpenEn - ptOpenSt ; + vtFirst.Normalize() ; + bFirstInside = vtLast * ( vtFirst ^ vtExtr) < 0. ; + } + pOpen = cvOpenLoopVec[nLastOpenLoopN].GetNextCurve() ; + } + // Dalla fine del loop aperto alla fine del segmento corrente + ptSegSt = ptOpenLoopEnP ; + pCv->GetEndPoint( ptSegEn) ; + cvSeg ; + cvSeg.Set( ptSegSt, ptSegEn) ; + cvSplitLoop1.AddCurve( cvSeg) ; + bFirstSt = true ; + } + // Devo percorrere il loop aperto contro il suo verso + else { + // Dall'inizio del segmento corrente fino alla fine del loop aperto + ptSegEn = ptOpenLoopEnP ; + CurveLine cvSeg ; + cvSeg.Set( ptSegSt, ptSegEn) ; + cvSplitLoop1.AddCurve( cvSeg) ; + // Loop aperto + const ICurve* pOpenLast = cvOpenLoopVec[nLastOpenLoopN].GetLastCurve() ; + const ICurve* pOpen = pOpenLast ; + while ( pOpen != nullptr) { + Point3d ptOpenSt, ptOpenEn ; + pOpen->GetStartPoint( ptOpenSt) ; + pOpen->GetEndPoint( ptOpenEn) ; + CurveLine cvOpenSeg ; + cvOpenSeg.Set( ptOpenEn, ptOpenSt) ; + cvSplitLoop1.AddCurve( cvOpenSeg) ; + if ( pOpen == pOpenLast) { + Vector3d vtLast = ptSegSt - ptSegEn ; + vtLast.Normalize() ; + Vector3d vtFirst = ptOpenEn - ptOpenSt ; + vtFirst.Normalize() ; + bFirstInside = vtLast * ( vtFirst ^ vtExtr) < 0. ; + } + pOpen = cvOpenLoopVec[nLastOpenLoopN].GetPrevCurve() ; + } + // Dall'inizio del loop aperto fino alla fine del segmento corrente + ptSegSt = ptOpenLoopStP ; + pCv->GetEndPoint( ptSegEn) ; + cvSeg ; + cvSeg.Set( ptSegSt, ptSegEn) ; + cvSplitLoop1.AddCurve( cvSeg) ; + bFirstSt = false ; + } + } + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + } + // Creo secondo loop + if ( bFirstSt) { + // Tratto segmento ove cadono gli estremi del loop aperto + CurveLine cvSeg ; + cvSeg.Set( ptOpenLoopStP, ptOpenLoopEnP) ; + cvSplitLoop2.AddCurve( cvSeg) ; + // Loop aperto + const ICurve* pOpen = cvOpenLoopVec[nLastOpenLoopN].GetLastCurve(); + while (pOpen != nullptr) { + Point3d ptOpenSt, ptOpenEn; + pOpen->GetStartPoint(ptOpenSt); + pOpen->GetEndPoint(ptOpenEn); + CurveLine cvOpenSeg; + cvOpenSeg.Set(ptOpenEn, ptOpenSt); + cvSplitLoop2.AddCurve(cvOpenSeg); + pOpen = cvOpenLoopVec[nLastOpenLoopN].GetPrevCurve(); + } + } + else { + // Tratto segmento ove cadono gli estremi del loop aperto + CurveLine cvSeg ; + cvSeg.Set( ptOpenLoopEnP, ptOpenLoopStP) ; + cvSplitLoop2.AddCurve( cvSeg) ; + // Loop aperto + const ICurve* pOpen = cvOpenLoopVec[nLastOpenLoopN].GetFirstCurve() ; + while ( pOpen != nullptr) { + Point3d ptOpenSt, ptOpenEn ; + pOpen->GetStartPoint( ptOpenSt) ; + pOpen->GetEndPoint( ptOpenEn) ; + CurveLine cvOpenSeg ; + cvOpenSeg.Set( ptOpenSt, ptOpenEn) ; + cvSplitLoop2.AddCurve( cvOpenSeg); + pOpen = cvOpenLoopVec[nLastOpenLoopN].GetNextCurve() ; + } + } + // Aggiungo i nuovi loop nel vettore + cvBoundClosedLoopVec[nL] = cvSplitLoop1 ; + cvBoundClosedLoopVec.emplace_back( cvSplitLoop2) ; + vbInOut[nL] = bFirstInside ; + vbInOut.push_back( ! bFirstInside) ; + } + // Estremi dell'aperto su due diversi segmenti del chiuso + else { + bool bFirstInside ; + bool bFirstSt ; + CurveComposite cvSplitLoop1, cvSplitLoop2 ; + // Creo primo loop + pCv = cvBoundClosedLoopVec[nL].GetFirstCurve() ; + while ( pCv != nullptr) { + // Segmento su cui non incide nessun estremo del loop aperto + if ( pCv != pCvSt && pCv != pCvEn) { + Point3d ptSegSt, ptSegEn ; + pCv->GetStartPoint( ptSegSt) ; + pCv->GetEndPoint( ptSegEn) ; + CurveLine cvSeg ; + cvSeg.Set( ptSegSt, ptSegEn) ; + cvSplitLoop1.AddCurve( cvSeg) ; + } + // Segmento su cui incide l'estremo iniziale del loop aperto + else if ( pCv == pCvSt) { + // Dall'inizio del segmento corrente fino all'inizio del loop aperto + Point3d ptSegSt ; + pCv->GetStartPoint( ptSegSt) ; + CurveLine cvSeg ; + cvSeg.Set( ptSegSt, ptOpenLoopStP) ; + cvSplitLoop1.AddCurve( cvSeg) ; + // Loop aperto + const ICurve* pOpenFirst = cvOpenLoopVec[nLastOpenLoopN].GetFirstCurve(); + const ICurve* pOpen = pOpenFirst ; + while ( pOpen != nullptr) { + // Valuto se cvSplitLoop1 è interno o esterno + Point3d ptOpenSt, ptOpenEn ; + pOpen->GetStartPoint( ptOpenSt) ; + pOpen->GetEndPoint( ptOpenEn) ; + CurveLine cvOpenSeg ; + cvOpenSeg.Set( ptOpenSt, ptOpenEn) ; + cvSplitLoop1.AddCurve( cvOpenSeg) ; + if ( pOpen == pOpenFirst) { + Vector3d vtLast = ptSegSt - ptOpenLoopStP ; + vtLast.Normalize() ; + Vector3d vtFirst = ptOpenEn - ptOpenSt ; + vtFirst.Normalize() ; + bFirstInside = vtLast * ( vtFirst ^ vtExtr) < 0. ; + } + pOpen = cvOpenLoopVec[nLastOpenLoopN].GetNextCurve() ; + } + // Dalla fine del loop aperto fino alla fine del segmento ove arriva il loop aperto + while ( pCv != pCvEn) + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + Point3d ptSegEn ; + pCv->GetEndPoint( ptSegEn) ; + cvSeg ; + cvSeg.Set( ptOpenLoopEnP, ptSegEn) ; + cvSplitLoop1.AddCurve( cvSeg) ; + bFirstSt = true ; + } + // Segmento su cui incide l'estremo finale del loop aperto + else { + // Dall'inizio del segmento corrente fino alla fine del loop aperto + Point3d ptSegSt ; + pCv->GetStartPoint( ptSegSt) ; + CurveLine cvSeg ; + cvSeg.Set( ptSegSt, ptOpenLoopEnP) ; + cvSplitLoop1.AddCurve( cvSeg) ; + // Loop aperto + const ICurve* pOpenLast = cvOpenLoopVec[nLastOpenLoopN].GetLastCurve() ; + const ICurve* pOpen = pOpenLast ; + while ( pOpen != nullptr) { + Point3d ptOpenSt , ptOpenEn ; + pOpen->GetStartPoint( ptOpenSt) ; + pOpen->GetEndPoint( ptOpenEn) ; + CurveLine cvOpenSeg ; + cvOpenSeg.Set( ptOpenEn, ptOpenSt) ; + cvSplitLoop1.AddCurve( cvOpenSeg) ; + if ( pOpen == pOpenLast) { + Vector3d vtLast = ptSegSt - ptOpenLoopEnP ; + vtLast.Normalize() ; + Vector3d vtFirst = ptOpenEn - ptOpenSt ; + vtFirst.Normalize() ; + bFirstInside = vtLast * ( vtFirst ^ vtExtr) < 0. ; + } + pOpen = cvOpenLoopVec[nLastOpenLoopN].GetPrevCurve() ; + } + // Dalla fine del loop aperto fino alla fine del segmento ove arriva il loop aperto + while ( pCv != pCvSt) + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + Point3d ptSegEn ; + pCv->GetEndPoint( ptSegEn) ; + cvSeg.Set( ptOpenLoopStP, ptSegEn) ; + cvSplitLoop1.AddCurve( cvSeg) ; + bFirstSt = false ; + } + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + } + // Creo secondo loop + if ( bFirstSt) { + // Individuo il segmento ove incide l'estremo iniziale del loop aperto + pCv = cvBoundClosedLoopVec[nL].GetFirstCurve() ; + while ( pCv != pCvSt) + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + // Dall'estremo finale del loop aperto alla fine del segmento su cui giace + Point3d ptSegSt, ptSegEn ; + ptSegSt = ptOpenLoopStP ; + pCv->GetEndPoint( ptSegEn) ; + CurveLine cvSeg ; + cvSeg.Set( ptSegSt, ptSegEn) ; + cvSplitLoop2.AddCurve( cvSeg) ; + // Loop chiuso fino a segmento ove cade l'estremo finale dell'aperto + const ICurve* pCvStop = pCvEn ; + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + if ( pCv == nullptr) + pCv = cvBoundClosedLoopVec[nL].GetFirstCurve() ; + while ( pCv != pCvStop) { + if ( pCv == nullptr) + pCv = cvBoundClosedLoopVec[nL].GetFirstCurve() ; + pCv->GetStartPoint( ptSegSt) ; + pCv->GetEndPoint( ptSegEn) ; + CurveLine cvSeg ; + cvSeg.Set( ptSegSt, ptSegEn) ; + cvSplitLoop2.AddCurve( cvSeg) ; + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + } + // Dall'inizio del segmento del loop chiuso ove cade l'estremo finale del loop aperto + // a quest'ultimo + pCv->GetStartPoint( ptSegSt) ; + ptSegEn = ptOpenLoopEnP ; + cvSeg.Set( ptSegSt, ptOpenLoopEnP) ; + cvSplitLoop2.AddCurve( cvSeg) ; + // Loop aperto + const ICurve* pOpen = cvOpenLoopVec[nLastOpenLoopN].GetLastCurve() ; + while ( pOpen != nullptr) { + Point3d ptOpenSt, ptOpenEn ; + pOpen->GetStartPoint( ptOpenSt) ; + pOpen->GetEndPoint( ptOpenEn) ; + CurveLine cvOpenSeg ; + cvOpenSeg.Set( ptOpenEn, ptOpenSt) ; + cvSplitLoop2.AddCurve( cvOpenSeg) ; + pOpen = cvOpenLoopVec[nLastOpenLoopN].GetPrevCurve() ; + } + } + else { + // Individuo il segmento ove incide l'estremo finale del loop aperto + pCv = cvBoundClosedLoopVec[nL].GetFirstCurve() ; + while ( pCv != pCvEn) + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + // Dall'estremo finale del loop aperto alla fine del segmento su cui giace + Point3d ptSegSt, ptSegEn ; + ptSegSt = ptOpenLoopEnP ; + pCv->GetEndPoint( ptSegEn) ; + CurveLine cvSeg ; + cvSeg.Set( ptSegSt, ptSegEn) ; + cvSplitLoop2.AddCurve( cvSeg) ; + // Loop chiuso fino al segmento ove cade l'inizio del loop aperto + const ICurve* pCvStop = pCvSt ; + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + if ( pCv == nullptr) + pCv = cvBoundClosedLoopVec[nL].GetFirstCurve() ; + while ( pCv != pCvStop) { + if ( pCv == nullptr) + pCv = cvBoundClosedLoopVec[nL].GetFirstCurve() ; + pCv->GetStartPoint( ptSegSt) ; + pCv->GetEndPoint( ptSegEn) ; + CurveLine cvSeg ; + cvSeg.Set( ptSegSt, ptSegEn) ; + cvSplitLoop2.AddCurve( cvSeg) ; + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + } + // Dall'inizio del segmento del loop chiuso ove cade l'estremo iniziale del loop aperto + // a quest'ultimo + pCv->GetStartPoint( ptSegSt) ; + ptSegEn = ptOpenLoopStP ; + cvSeg.Set( ptSegSt, ptOpenLoopStP) ; + cvSplitLoop2.AddCurve( cvSeg) ; + // Loop aperto + const ICurve* pOpen = cvOpenLoopVec[nLastOpenLoopN].GetFirstCurve() ; + while ( pOpen != nullptr) { + Point3d ptOpenSt, ptOpenEn ; + pOpen->GetStartPoint( ptOpenSt); + pOpen->GetEndPoint( ptOpenEn); + CurveLine cvOpenSeg ; + cvOpenSeg.Set( ptOpenSt, ptOpenEn) ; + cvSplitLoop2.AddCurve( cvOpenSeg) ; + pOpen = cvOpenLoopVec[nLastOpenLoopN].GetNextCurve() ; + } + } + // Aggiungo i nuovi loop nel vettore + cvBoundClosedLoopVec[nL] = cvSplitLoop1 ; + cvBoundClosedLoopVec.emplace_back( cvSplitLoop2) ; + vbInOut[nL] = bFirstInside ; + vbInOut.push_back( ! bFirstInside) ; + } + } + } + cvOpenLoopVec.resize( nLastOpenLoopN) ; + } + RemoveTriangle( nT) ; + // Trasformo i loop compositi in loop polyline + std::vector vplPolyVec ; + vplPolyVec.resize( cvBoundClosedLoopVec.size()) ; + for ( int nL = 0 ; nL < int( vplPolyVec.size()) ; ++ nL) { + const ICurve* pCv = cvBoundClosedLoopVec[nL].GetFirstCurve() ; + while ( pCv != nullptr) { + // Estremi del segmento corrente del loop chiuso corrente + Point3d ptSegSt, ptSegEn ; + pCv->GetStartPoint( ptSegSt) ; + pCv->GetEndPoint( ptSegEn) ; + vplPolyVec[nL].AddUPoint( 0., ptSegSt) ; + vplPolyVec[nL].AddUPoint( 0., ptSegEn) ; + pCv = cvBoundClosedLoopVec[nL].GetNextCurve() ; + } + if ( vbInOut[nL]) { + // Poligonalizzo il loop + Triangulate CreateTriangulation ; + PNTVECTOR vPt ; + INTVECTOR vTr ; + CreateTriangulation.Make( vplPolyVec[nL], vPt, vTr) ; + // Aggiungo i triangoli + for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { + int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2] } ; + int nNewId[3] = { AddVertex(vPt[nNewTriaVertId[0]]), + AddVertex(vPt[nNewTriaVertId[1]]), + AddVertex(vPt[nNewTriaVertId[2]]) } ; + AddTriangle( nNewId) ; + bModif = true ; + } + } + } + } + else if ( nVertInside == 0) + RemoveTriangle( nT) ; + } + // L'orientamento del loop non stabilise i vertici dentro e fuori + else { + std::vector vTriaVec ; + TriaInOut trStartTria ; + trStartTria.trTria = trTria ; + trStartTria.bTriaInside = true ; + vTriaVec.emplace_back( trStartTria) ; + vTriaVec.resize( 1) ; + // Ciclo sui segmenti + Point3d ptSt, ptEn ; + bool bContinue = plLine.GetFirstLine( ptSt, ptEn) ; + while ( bContinue) { + for ( int nTr = 0 ; nTr < int( vTriaVec.size()) ; ++ nTr) { + Point3d ptSegSt, ptSegEn ; + // C'è interferenza fra il rettangolo, ottenuto dall'estrusione del segmento corrente, e il triangolo + if ( FindRectangleTriangleIntersectionSegment2( ptSt + vtMin, ptEn + vtMin, ptEn + vtMax, ptSt + vtMax, + vTriaVec[nTr].trTria, ptSegSt, ptSegEn)) { + // Stabilisco su quali lati del triangolo cadono gli estremi del segmento intersezione + int nStEdge = -1 ; + int nEnEdge = -1 ; + for ( int nV = 0 ; nV < 3 ; ++ nV) { + int nW = (nV + 1) % 3 ; + Point3d ptVertV = vTriaVec[nTr].trTria.GetP( nV) ; + Point3d ptVertW = vTriaVec[nTr].trTria.GetP( nW) ; + DistPointLine dStDistCalc( ptSegSt, ptVertV, ptVertW) ; + DistPointLine dEnDistCalc( ptSegEn, ptVertV, ptVertW) ; + double dSqDistSt ; + dStDistCalc.GetSqDist( dSqDistSt) ; + if ( dSqDistSt < EPS_SMALL * EPS_SMALL) + nStEdge = nV ; + double dSqDistEn ; + dEnDistCalc.GetSqDist( dSqDistEn) ; + if ( dSqDistEn < EPS_SMALL * EPS_SMALL) + nEnEdge = nV ; + } + int nMinInd, nMaxInd ; + Point3d ptMin, ptMax ; + if ( nStEdge < nEnEdge) { + nMinInd = nStEdge ; + nMaxInd = nEnEdge ; + ptMin = ptSegSt ; + ptMax = ptSegEn ; + } + else { + nMinInd = nEnEdge ; + nMaxInd = nStEdge ; + ptMin = ptSegEn ; + ptMax = ptSegSt ; + } + TriaInOut trSingleTria ; + PolyLine plInnerLoop ; + bool bLoopInside ; + if ( nMaxInd == ( nMinInd + 1) % 3) { + trSingleTria.trTria.SetP( 0, ptMin) ; + trSingleTria.trTria.SetP( 1, vTriaVec[nTr].trTria.GetP( ( nMinInd + 1) % 3)) ; + trSingleTria.trTria.SetP( 2, ptMax) ; + Vector3d vtTan = ptEn - ptSt ; + vtTan.Normalize() ; + if ( ( trSingleTria.trTria.GetP(1) - trSingleTria.trTria.GetP(0)) * ( vtTan ^ vtExtr) < 0.) + trSingleTria.bTriaInside = true ; + else + trSingleTria.bTriaInside = false ; + trSingleTria.trTria.Validate( true) ; + plInnerLoop.AddUPoint( 0., ptMin) ; + plInnerLoop.AddUPoint( 0., ptMax) ; + plInnerLoop.AddUPoint( 0., vTriaVec[nTr].trTria.GetP( ( nMinInd + 2) % 3)) ; + plInnerLoop.AddUPoint( 0., vTriaVec[nTr].trTria.GetP( nMinInd)) ; + plInnerLoop.AddUPoint( 0., ptMin) ; + if ( ( vTriaVec[nTr].trTria.GetP( nMinInd) - ptMin) * ( vtTan ^ vtExtr) < 0.) + bLoopInside = true ; + else + bLoopInside = false ; + } + else { + trSingleTria.trTria.SetP( 0, ptMin) ; + trSingleTria.trTria.SetP( 1, ptMax) ; + trSingleTria.trTria.SetP( 2, vTriaVec[nTr].trTria.GetP( nMinInd)) ; + Vector3d vtTan = ptEn - ptSt ; + vtTan.Normalize() ; + if ( ( trSingleTria.trTria.GetP( 2) - trSingleTria.trTria.GetP( 0)) * ( vtTan ^ vtExtr) < 0.) + trSingleTria.bTriaInside = true ; + else + trSingleTria.bTriaInside = false ; + trSingleTria.trTria.Validate( true) ; + plInnerLoop.AddUPoint( 0., ptMin) ; + plInnerLoop.AddUPoint( 0., vTriaVec[nTr].trTria.GetP( ( nMinInd + 1) % 3)) ; + plInnerLoop.AddUPoint( 0., vTriaVec[nTr].trTria.GetP( ( nMinInd + 2) % 3)) ; + plInnerLoop.AddUPoint( 0., ptMax) ; + plInnerLoop.AddUPoint( 0., ptMin) ; + if ( ( vTriaVec[nTr].trTria.GetP( ( nMinInd + 1) % 3) - ptMin) * ( vtTan ^ vtExtr) < 0.) + bLoopInside = true ; + else + bLoopInside = false ; + } + // Poligonalizzo il loop + Triangulate CreateTriangulation ; + PNTVECTOR vPt ; + INTVECTOR vTr ; + CreateTriangulation.Make( plInnerLoop, vPt, vTr) ; + // Aggiungo i triangoli al vettore + int nOldSize = int( vTriaVec.size()) ; + int nAddSize = int( vTr.size() / 3) ; + vTriaVec.resize( nOldSize + nAddSize) ; + for ( int m = nOldSize - 1 ; m > nTr ; -- m) { + vTriaVec[m + nAddSize] = vTriaVec[m] ; + } + vTriaVec[nTr] = trSingleTria ; + for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { + int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2] } ; + TriaInOut trNewTria ; + trNewTria.trTria.SetP( 0, vPt[nNewTriaVertId[0]]) ; + trNewTria.trTria.SetP( 1, vPt[nNewTriaVertId[1]]) ; + trNewTria.trTria.SetP( 2, vPt[nNewTriaVertId[2]]) ; + trNewTria.trTria.Validate( true) ; + trNewTria.bTriaInside = bLoopInside ; + vTriaVec[nTr + 1 + (n / 3)] = trNewTria ; + } + -- nTr ; + } + } + bContinue = plLine.GetNextLine( ptSt, ptEn) ; + } + // Se non sono state trovate intersezioni col triangolo + if ( vTriaVec.size() == 1) { + // Se almeno un punto interno (sotto l'ipotesi di nessuna intersezione + // equivale a tre punti interni) deve essere conservato così com'è. + if ( nVertInside > 0) + continue ; + // Altrimenti il triangolo deve essere eliminato + else { + RemoveTriangle( nT) ; + continue ; + } + } + RemoveTriangle( nT) ; + bModif = true ; + // Aggiungo i triangoli alla trimesh + for ( int n = 0 ; n < int( vTriaVec.size()) ; ++ n) { + if ( vTriaVec[n].bTriaInside) { + int nNewId[3] = { AddVertex(vTriaVec[n].trTria.GetP( 0)), + AddVertex(vTriaVec[n].trTria.GetP( 1)), + AddVertex(vTriaVec[n].trTria.GetP( 2)) } ; + AddTriangle( nNewId) ; + } + } + } + } + + // Se avvenuta modifica, aggiorno tutto + if ( bModif) + return ( AdjustVertices() && DoCompacting()) ; + + return true ; +}