diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj
index 1d7bc11..48dc5a0 100644
--- a/EgtGeomKernel.vcxproj
+++ b/EgtGeomKernel.vcxproj
@@ -309,6 +309,7 @@ copy $(TargetPath) \EgtProg\Dll64
+
@@ -316,6 +317,8 @@ copy $(TargetPath) \EgtProg\Dll64
+
+
@@ -628,7 +631,6 @@ copy $(TargetPath) \EgtProg\Dll64
-
diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters
index d101d64..1f8e8f8 100644
--- a/EgtGeomKernel.vcxproj.filters
+++ b/EgtGeomKernel.vcxproj.filters
@@ -49,6 +49,9 @@
{d96752da-1884-4a73-ba1b-5b20b606e469}
+
+ {4c6a9dc5-8fac-4ecd-bde6-3e37e056712e}
+
@@ -504,6 +507,9 @@
File di origine\Base
+
+ File di origine\GeoElevation
+
@@ -1148,15 +1154,18 @@
File di intestazione
-
- File di intestazione\Include
-
File di intestazione
File di intestazione
+
+ File di intestazione\Include
+
+
+ File di intestazione\Include
+
diff --git a/Polygon3d.cpp b/Polygon3d.cpp
index ee20680..2892c69 100644
--- a/Polygon3d.cpp
+++ b/Polygon3d.cpp
@@ -471,6 +471,18 @@ Polygon3d::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
return true ;
}
+//----------------------------------------------------------------------------
+bool
+Polygon3d::GetLocalBBox( BBox3d& b3Loc) const
+{
+ // assegno il box in locale, scorrendo tutti i punti del contorno
+ b3Loc.Reset() ;
+ for ( const auto& ptP : m_vVert)
+ b3Loc.Add( ptP) ;
+
+ return true ;
+}
+
//----------------------------------------------------------------------------
void
Polygon3d::Invert( void)
diff --git a/PolygonElevation.cpp b/PolygonElevation.cpp
new file mode 100644
index 0000000..c17abef
--- /dev/null
+++ b/PolygonElevation.cpp
@@ -0,0 +1,224 @@
+//----------------------------------------------------------------------------
+// EgalTech 2023-2023
+//----------------------------------------------------------------------------
+// File : PolygonElevation.cpp Data : 17.12.23 Versione : 2.5l3
+// Contenuto : Implementazione di funzioni per calcolo elevazione di
+// un poligono (faccia piana) in solidi di diverso tipo.
+//
+//
+// Modifiche : 17.12.23 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "CurveLine.h"
+#include "CurveComposite.h"
+#include "/EgtDev/Include/EGkIntersLineBox.h"
+#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
+#include "/EgtDev/Include/EGkIntersCurves.h"
+#include "/EgtDev/Include/EGkPolygonElevation.h"
+
+using namespace std ;
+
+//-------------------------------------------------------------------------------
+bool
+PolygonElevationInBBox( const Polygon3d& pgFacet, const BBox3d& b3Box, bool bAcceptOutFacet, double& dElev)
+{
+ // verifico validità del poligono e del box
+ if ( ! pgFacet.IsValid() || b3Box.IsEmpty())
+ return false ;
+
+ // se richiesto, verifico che la faccia sia contenuta nel box
+ if ( ! bAcceptOutFacet) {
+ BBox3d b3Fac ;
+ if ( ! pgFacet.GetLocalBBox( b3Fac))
+ return false ;
+ BBox3d b3ExpBox = b3Box ; b3ExpBox.Expand( 100 * EPS_SMALL) ;
+ if ( ! b3ExpBox.Encloses( b3Fac)) {
+ dElev = -1 ;
+ return true ;
+ }
+ }
+
+ // recupero centro, normale e contorno delle faccia poligonale
+ Point3d ptCen = pgFacet.GetCentroid() ;
+ Vector3d vtN = pgFacet.GetVersN() ;
+ PolyLine PL = pgFacet.GetPolyLine() ;
+
+ // calcolo elevazione massima del contorno della faccia
+ const double RAY_LEN = 100000 ;
+ dElev = 0 ;
+ Point3d ptP ;
+ bool bFound = PL.GetFirstPoint( ptP) ;
+ while ( bFound) {
+ INTDBLVECTOR vInters ;
+ IntersLineBox( ptP, vtN, RAY_LEN, b3Box, vInters, true) ;
+ for ( int i = 0 ; i < int( vInters.size()) ; ++ i) {
+ if ( i == 0 && ( vInters[i].first == ILBT_IN || vInters[i].first == ILBT_TG_INI)) {
+ if ( ! bAcceptOutFacet && vInters[i].second > 100 * EPS_SMALL) {
+ dElev = -1 ;
+ return true ;
+ }
+ }
+ else if ( vInters[i].first == ILBT_OUT || vInters[i].first == ILBT_TG_FIN)
+ dElev = max( dElev, vInters[i].second) ;
+ }
+ bFound = PL.GetNextPoint( ptP, true) ;
+ }
+
+ // calcolo elevazione massima degli eventuali spigoli (e vertici) del box dalla parte positiva della faccia e che cadono in essa
+ BIPNTVECTOR vEdges( 12) ;
+ vEdges[0].first = b3Box.GetMin() ; vEdges[0].second = vEdges[0].first + b3Box.GetDimX() * X_AX ;
+ vEdges[1].first = vEdges[0].second ; vEdges[1].second = vEdges[1].first + b3Box.GetDimY() * Y_AX ;
+ vEdges[2].first = vEdges[1].second ; vEdges[2].second = vEdges[0].first + b3Box.GetDimY() * Y_AX ;
+ vEdges[3].first = vEdges[2].second ; vEdges[3].second = vEdges[0].first ;
+ vEdges[4].first = vEdges[0].first + b3Box.GetDimZ() * Z_AX ; vEdges[4].second = vEdges[0].second + b3Box.GetDimZ() * Z_AX ;
+ vEdges[5].first = vEdges[1].first + b3Box.GetDimZ() * Z_AX ; vEdges[5].second = vEdges[1].second + b3Box.GetDimZ() * Z_AX ;
+ vEdges[6].first = vEdges[2].first + b3Box.GetDimZ() * Z_AX ; vEdges[6].second = vEdges[2].second + b3Box.GetDimZ() * Z_AX ;
+ vEdges[7].first = vEdges[3].first + b3Box.GetDimZ() * Z_AX ; vEdges[7].second = vEdges[3].second + b3Box.GetDimZ() * Z_AX ;
+ vEdges[8].first = vEdges[0].first ; vEdges[8].second = vEdges[4].first ;
+ vEdges[9].first = vEdges[1].first ; vEdges[9].second = vEdges[5].first ;
+ vEdges[10].first = vEdges[2].first ; vEdges[10].second = vEdges[6].first ;
+ vEdges[11].first = vEdges[3].first ; vEdges[11].second = vEdges[7].first ;
+ // porto tutto nel riferimento intrinseco della faccia (già calcolato in quello del box)
+ Frame3d frOcs ; frOcs.Set( ptCen, vtN) ;
+ PL.ToLoc( frOcs) ;
+ for ( int i = 0 ; i < int( vEdges.size()) ; ++ i) {
+ vEdges[i].first.ToLoc( frOcs) ;
+ vEdges[i].second.ToLoc( frOcs) ;
+ }
+ // calcolo la curva di loop
+ CurveComposite ccLoop ;
+ if ( ! ccLoop.FromPolyLine( PL))
+ return false ;
+ // eseguo i calcoli di elevazione
+ for ( int i = 0 ; i < int( vEdges.size()) ; ++ i) {
+ // se sta sul piano o sotto, lo salto
+ if ( vEdges[i].first.z < EPS_SMALL && vEdges[i].second.z < EPS_SMALL)
+ continue ;
+ // calcolo il segmento di linea
+ CurveLine clLine ;
+ if ( ! clLine.Set( vEdges[i].first, vEdges[i].second))
+ return false ;
+ // l'elevazione va aggiornata con la massima Z delle eventuali intersezioni dell'edge con il loop
+ IntersCurveCurve intLL( clLine, ccLoop) ;
+ IntCrvCrvInfo aInfo ;
+ for ( int j = 0 ; intLL.GetIntCrvCrvInfo( j, aInfo) ; ++ j) {
+ dElev = max( dElev, aInfo.IciA[0].ptI.z) ;
+ if ( aInfo.bOverlap)
+ dElev = max( dElev, aInfo.IciA[1].ptI.z) ;
+ // se prima intersezione va da interno ad esterno allora devo considerare il punto iniziale del segmento (vertice)
+ if ( j == 0 && aInfo.IciA[0].nPrevTy == ICCT_IN)
+ dElev = max( dElev, vEdges[i].first.z) ;
+ // c'è anche il caso di ultima intersezione da esterno a interno, ma vertice già considerato nel caso precedente
+ }
+ }
+
+ return true ;
+}
+
+//-------------------------------------------------------------------------------
+bool
+PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& CldStm, bool bAcceptOutFacet, double& dElev)
+{
+ // verifico validità del poligono e della superficie
+ if ( ! pgFacet.IsValid() || ! CldStm.IsValid() || ! CldStm.IsClosed())
+ return false ;
+
+ // se superficie vuota
+ if ( CldStm.IsEmpty()) {
+ dElev = ( bAcceptOutFacet ? 0 : -1) ;
+ return true ;
+ }
+
+ // se richiesto, verifico sia contenuta nel box della superficie chiusa
+ if ( ! bAcceptOutFacet) {
+ BBox3d b3Fac ;
+ if ( ! pgFacet.GetLocalBBox( b3Fac))
+ return false ;
+ BBox3d b3ExpCldStm ; CldStm.GetLocalBBox( b3ExpCldStm) ; b3ExpCldStm.Expand( 100 * EPS_SMALL) ;
+ if ( ! b3ExpCldStm.Encloses( b3Fac)) {
+ dElev = -1 ;
+ return true ;
+ }
+ }
+
+ // recupero centro, normale e contorno delle faccia poligonale
+ Point3d ptCen = pgFacet.GetCentroid() ;
+ Vector3d vtN = pgFacet.GetVersN() ;
+ PolyLine PL = pgFacet.GetPolyLine() ;
+
+ // calcolo elevazione massima del contorno della faccia
+ const double RAY_LEN = 100000 ;
+ dElev = 0 ;
+ Point3d ptP ;
+ bool bFound = PL.GetFirstPoint( ptP) ;
+ while ( bFound) {
+ ILSIVECTOR vInters ;
+ IntersLineSurfTm( ptP, vtN, RAY_LEN, CldStm, vInters, true) ;
+ for ( int i = 0 ; i < int( vInters.size()) ; ++ i) {
+ const auto& Inters = vInters[i] ;
+ if ( i == 0 && Inters.nILTT != ILTT_NO && Inters.dCosDN < -EPS_ZERO) {
+ if ( ! bAcceptOutFacet && Inters.dU > 100 * EPS_SMALL) {
+ dElev = -1 ;
+ return true ;
+ }
+ }
+ else if ( ( Inters.nILTT == ILTT_VERT || Inters.nILTT == ILTT_EDGE || Inters.nILTT == ILTT_IN) && Inters.dCosDN > EPS_ZERO)
+ dElev = max( dElev, Inters.dU) ;
+ else if ( Inters.nILTT == ILTT_SEGM || Inters.nILTT == ILTT_SEGM_ON_EDGE)
+ dElev = max( dElev, Inters.dU2) ;
+ }
+ bFound = PL.GetNextPoint( ptP, true) ;
+ }
+ // calcolo elevazione massima degli eventuali spigoli (e vertici) della superficie chiusa dalla parte positiva della faccia e che cadono in essa
+ int nEdgeCnt = CldStm.GetEdgeCount() ;
+ if ( nEdgeCnt < 0)
+ return false ;
+ BIPNTVECTOR vEdges ;
+ vEdges.reserve( nEdgeCnt) ;
+ for ( int i = 0 ; i < nEdgeCnt ; ++ i) {
+ Point3d ptP1, ptP2 ; double dAng ;
+ CldStm.GetEdge( i, ptP1, ptP2, dAng) ;
+ vEdges.emplace_back( ptP1, ptP2) ;
+ }
+ // porto tutto nel riferimento intrinseco della faccia (già calcolato in quello della superficie chiusa)
+ Frame3d frOcs ; frOcs.Set( ptCen, vtN) ;
+ PL.ToLoc( frOcs) ;
+ for ( int i = 0 ; i < int( vEdges.size()) ; ++ i) {
+ vEdges[i].first.ToLoc( frOcs) ;
+ vEdges[i].second.ToLoc( frOcs) ;
+ }
+ // calcolo la curva di loop
+ CurveComposite ccLoop ;
+ if ( ! ccLoop.FromPolyLine( PL))
+ return false ;
+ // eseguo i calcoli di elevazione
+ for ( int i = 0 ; i < int( vEdges.size()) ; ++ i) {
+ // se sta sul piano o sotto, lo salto
+ if ( vEdges[i].first.z < EPS_SMALL && vEdges[i].second.z < EPS_SMALL)
+ continue ;
+ // calcolo il segmento di linea
+ CurveLine clLine ;
+ if ( ! clLine.Set( vEdges[i].first, vEdges[i].second))
+ return false ;
+ // l'elevazione va aggiornata con la massima Z delle eventuali intersezioni dell'edge con il loop
+ IntersCurveCurve intLL( clLine, ccLoop) ;
+ IntCrvCrvInfo aInfo ;
+ for ( int j = 0 ; intLL.GetIntCrvCrvInfo( j, aInfo) ; ++ j) {
+ dElev = max( dElev, aInfo.IciA[0].ptI.z) ;
+ if ( aInfo.bOverlap)
+ dElev = max( dElev, aInfo.IciA[1].ptI.z) ;
+ // se prima intersezione va da interno ad esterno allora devo considerare il punto iniziale del segmento (vertice)
+ if ( j == 0 && aInfo.IciA[0].nPrevTy == ICCT_IN)
+ dElev = max( dElev, vEdges[i].first.z) ;
+ // se ultima intersezione va da esterno a interno allora devo considerare il punto finale del segmento (vertice)
+ else if ( j == intLL.GetIntersCount() - 1 && aInfo.IciA[ aInfo.bOverlap ? 1 : 0].nNextTy == ICCT_IN)
+ dElev = max( dElev, vEdges[i].second.z) ;
+ }
+ }
+
+ return true ;
+}
diff --git a/SurfAux.h b/SurfAux.h
index 09867fc..68b116d 100644
--- a/SurfAux.h
+++ b/SurfAux.h
@@ -14,20 +14,3 @@
#pragma once
#include "/EgtDev/Include/EGkSurfAux.h"
-
-//----------------------------------------------------------------------------
-//bool IsClosed( const ICurve& crvC) ;
-//bool IsValidParam( const ICurve& crvC, double dPar, ICurve::Side nSide) ;
-//bool IsStartParam( const ICurve& crvC, double dPar) ;
-//bool IsEndParam( const ICurve& crvC, double dPar) ;
-//bool GetNearestExtremityToPoint( const Point3d& ptP, const ICurve& Curve, bool& bStart) ;
-//bool MoveParamToAvoidTg( double& dU, ICurve::Side nSide, const ICurve& Curve) ;
-//bool GetTang( const ICurve& crvC, double dU, ICurve::Side nS, Vector3d& vtTang) ;
-//bool GetPointTang( const ICurve& crvC, double dU, ICurve::Side nS, Point3d& ptPos, Vector3d& vtTang) ;
-//bool GetPointDiffGeom( const ICurve& crvC, double dU, ICurve::Side nS, CrvPointDiffGeom& oDiffG) ;
-//bool ImproveCurveParamAtPoint( double& dU, const Point3d& ptP, const ICurve* pCrv) ;
-//bool CurveGetAreaXY( const ICurve& crvC, double& dArea) ;
-//bool CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea) ;
-//bool CurveDump( const ICurve& crvC, std::string& sOut, bool bMM, const char* szNewLine) ;
-//bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
-//bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
diff --git a/SurfTriMeshFaceting.cpp b/SurfTriMeshFaceting.cpp
index 4a11734..66422c1 100644
--- a/SurfTriMeshFaceting.cpp
+++ b/SurfTriMeshFaceting.cpp
@@ -939,10 +939,10 @@ SurfTriMesh::GetEdgeCount( void) const
{
// la superficie deve essere validata
if ( m_nStatus != OK)
- return 0 ;
+ return -1 ;
// verifico stato bordi sfaccettatura
if ( ! VerifyFacetEdging())
- return 0 ;
+ return -1 ;
// restituisco il numero
return int( m_vFacEdge.size()) ;
}
@@ -985,7 +985,7 @@ SurfTriMesh::GetEdge( int nInd, Point3d& ptP1, Point3d& ptP2, double& dAng) cons
return SVT_NULL ;
// recupero i dati
ptP1 = m_vVert[m_vFacEdge[nInd].nIdVert[0]].ptP ;
- ptP2 = m_vVert[m_vFacEdge[nInd].nIdVert[0]].ptP ;
+ ptP2 = m_vVert[m_vFacEdge[nInd].nIdVert[1]].ptP ;
dAng = m_vFacEdge[nInd].dIntAng ;
// ritorno indice edge corrente
return true ;