EgtGeomKernel :

- aggiunte funzioni per calcolo elevazione di Poligono in Box e in TriMesh chiusa.
This commit is contained in:
Dario Sassi
2023-12-18 09:28:45 +01:00
parent 7c44a6ec82
commit c91c2a9720
6 changed files with 254 additions and 24 deletions
+3 -1
View File
@@ -309,6 +309,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="CurveByApprox.cpp" />
<ClCompile Include="CurveByInterp.cpp" />
<ClCompile Include="CurveCompositeOffset.cpp" />
<ClCompile Include="PolygonElevation.cpp" />
<ClCompile Include="Voronoi.cpp" />
<ClInclude Include="..\Include\EGkCDeClosedSurfTmClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeConeFrustumClosedSurfTm.h" />
@@ -316,6 +317,8 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="..\Include\EGkCDeRectPrismoidClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkIntersLineBox.h" />
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
<ClInclude Include="..\Include\EGkPolygonElevation.h" />
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h" />
<ClInclude Include="CDeBoxTria.h" />
<ClInclude Include="CDeCapsTria.h" />
<ClInclude Include="CDeConeFrustumTria.h" />
@@ -628,7 +631,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="FontOs.h" />
<ClInclude Include="AdjustLoops.h" />
<ClInclude Include="RemoveCurveDefects.h" />
<ClInclude Include="EGkSubtractProjectedFacesOnStmFace.h" />
<ClInclude Include="SurfAux.h" />
<ClInclude Include="SurfBezier.h" />
<ClInclude Include="SurfFlatRegion.h" />
+12 -3
View File
@@ -49,6 +49,9 @@
<Filter Include="File di origine\GeoProject">
<UniqueIdentifier>{d96752da-1884-4a73-ba1b-5b20b606e469}</UniqueIdentifier>
</Filter>
<Filter Include="File di origine\GeoElevation">
<UniqueIdentifier>{4c6a9dc5-8fac-4ecd-bde6-3e37e056712e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Vector3d.cpp">
@@ -504,6 +507,9 @@
<ClCompile Include="Voronoi.cpp">
<Filter>File di origine\Base</Filter>
</ClCompile>
<ClCompile Include="PolygonElevation.cpp">
<Filter>File di origine\GeoElevation</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@@ -1148,15 +1154,18 @@
<ClInclude Include="IntersLineCaps.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="EGkSubtractProjectedFacesOnStmFace.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="SurfAux.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="OffsetAux.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkPolygonElevation.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="EgtGeomKernel.rc">
+12
View File
@@ -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)
+224
View File
@@ -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 ;
}
-17
View File
@@ -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) ;
+3 -3
View File
@@ -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 ;