diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc
index a2b68f1..995ffe5 100644
Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ
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 ;
+}