Compare commits

...

24 Commits

Author SHA1 Message Date
Riccardo Elitropi 104726c5ee EgtGeomKernel :
- migliorie varie.
2024-03-19 09:01:46 +01:00
Riccardo Elitropi e2445c0a15 EgtGeomKernel :
- modifica Swept con vettore statico.
- aggiunta Swep con FlatRegion come sezione
- migliorie varie.
2024-03-18 13:20:35 +01:00
Riccardo Elitropi 9880fa0173 EgtGeomKernel :
- migliorie varie.
2024-03-15 13:17:41 +01:00
Riccardo Elitropi d276809906 EgtGeomKernel :
- Swept con o senza caps mediante RMF
- inizio stesura codice per frame statico
- migliorie varie.
2024-03-14 13:04:09 +01:00
Riccardo Elitropi 4268da4a1f EgtGeomKernel :
- primo codice di test con Caps per funzione Swept con guida non piana.
2024-03-11 13:22:37 +01:00
Riccardo Elitropi 4f485d0e87 EgtGeomKernel :
- primo codice di prova per creazione Swept.
2024-03-07 16:53:19 +01:00
Riccardo Elitropi d48348fa1c EgtGeomKernel :
- pulizia codice.
2024-03-07 10:51:59 +01:00
Riccardo Elitropi 003dd0bdef EgtGeomKernel :
- codice di prova per RMF.
2024-03-06 16:29:36 +01:00
Riccardo Elitropi ec109908fa EgtGeomKernel :
- inizio stesura codice per Rotation Minimize Frame.
2024-03-05 16:20:28 +01:00
SaraP 3630b85632 EgtGeomKernel :
- corretto errore offset regioni con Voronoi.
2024-03-04 16:19:27 +01:00
Dario Sassi fdce6e1853 EgtGeomKernel 2.6c1 :
- piccolissima aggiunta a offset di regioni.
2024-03-02 11:52:34 +01:00
SaraP 8ffa9d7fb7 EgtGeomKernel :
- corretto errore offset con Voronoi.
2024-03-01 16:50:55 +01:00
Dario Sassi 360484c9af EgtGeomKernel :
- correzioni a RemoveAlignedPoints di Polyline (si usano indici e non il parametro U come ordine dei punti).
2024-02-29 08:47:44 +01:00
Dario Sassi 47606bffcd Merge remote-tracking branch 'origin/Douglas-Peucker' 2024-02-28 17:36:44 +01:00
Dario Sassi aea99a635f EgtGeomKernel :
- eliminati salvataggi di debug dalle booleanne delle trimesh.
2024-02-27 18:25:01 +01:00
Dario Sassi ce139c6925 EgtGeomKernel 2.6b4 :
- aggiunta funzione GetSurfTriMeshTransSwept per creare superficie swept di traslazione.
2024-02-27 18:18:13 +01:00
SaraP 5dcf5f5616 EgtGeomKernel :
- in Voronoi deallocata memoria non utilizzata.
2024-02-27 14:27:17 +01:00
Dario Sassi 451ef8356b EgtGeomKernel :
- aggiunta funzione IntersCurveSurfTm
- funzioni di intersezione Line e Plane con Zmap separate dall'oggetto per l'interfaccia
2024-02-26 15:00:15 +01:00
Riccardo Elitropi 6e810f050e Merge commit 'bd90fc2b59f3167c57dc9f13d2a99b40c63883bc' 2024-02-21 17:04:26 +01:00
Riccardo Elitropi 6bfb5c619f Merge commit 'fae6a7cd78972d7b91457994d525dba16d4e5945' into Douglas-Peucker 2024-02-21 16:55:28 +01:00
Riccardo Elitropi 8be2246249 Merge commit '47e79756d17ae312d89d3617289bccabcb4bcf66' into Douglas-Peucker 2024-02-13 12:37:57 +01:00
Riccardo Elitropi 56cff98cf3 EgtGeomKernel :
- miglioria codice.
2024-02-06 13:15:13 +01:00
Riccardo Elitropi 3168bee865 Merge commit '7cd83efd97d2ab771362e2b18eb3db62bd9fb6e4' into Douglas-Peucker 2024-02-06 10:24:43 +01:00
Riccardo Elitropi 3d2f8c1495 EgtGeomKernel :
- approsimazione PolyLine con Douglas-Peucker.
2024-02-06 10:23:22 +01:00
19 changed files with 1459 additions and 237 deletions
BIN
View File
Binary file not shown.
+13
View File
@@ -309,14 +309,26 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="CurveByApprox.cpp" />
<ClCompile Include="CurveByInterp.cpp" />
<ClCompile Include="CurveCompositeOffset.cpp" />
<ClCompile Include="IntersCurveSurfTm.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="IntersLineVolZmap.cpp" />
<ClCompile Include="IntersPlaneVolZmap.cpp" />
<ClCompile Include="PolygonElevation.cpp" />
<ClCompile Include="RotationMinimizeFrame.cpp" />
<ClCompile Include="Voronoi.cpp" />
<ClInclude Include="..\Include\EGkCDeClosedSurfTmClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeConeFrustumClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeConvexTorusClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeRectPrismoidClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h" />
<ClInclude Include="..\Include\EGkIntersLineBox.h" />
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h" />
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h" />
<ClInclude Include="..\Include\EGkPolygonElevation.h" />
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h" />
<ClInclude Include="CDeBoxTria.h" />
@@ -449,6 +461,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="VolZmapGraphics.cpp" />
<ClCompile Include="VolZmapVolume.cpp" />
<ClCompile Include="VolZmap.cpp" />
<ClInclude Include="RotationMinimizeFrame.h" />
<ClInclude Include="Voronoi.h" />
</ItemGroup>
<ItemGroup>
+56 -29
View File
@@ -43,15 +43,18 @@
<Filter Include="File di origine\GeoOffset">
<UniqueIdentifier>{f07670fd-9429-4b7e-ac6d-1c0022e756fb}</UniqueIdentifier>
</Filter>
<Filter Include="File di origine\GeoCollision">
<UniqueIdentifier>{865b76ee-b10d-41fc-861c-b48ce52fa277}</UniqueIdentifier>
</Filter>
<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>
<Filter Include="File di origine\GeoCollisionAvoid">
<UniqueIdentifier>{ae52e402-3063-45e3-b9f7-1710035a1f56}</UniqueIdentifier>
</Filter>
<Filter Include="File di origine\GeoCollisionDetection">
<UniqueIdentifier>{865b76ee-b10d-41fc-861c-b48ce52fa277}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Vector3d.cpp">
@@ -372,17 +375,8 @@
<ClCompile Include="IntersLineSurfStd.cpp">
<Filter>File di origine\GeoInters</Filter>
</ClCompile>
<ClCompile Include="CAvToolTriangle.cpp">
<Filter>File di origine\GeoCollision</Filter>
</ClCompile>
<ClCompile Include="CAvToolSurfTm.cpp">
<Filter>File di origine\GeoCollision</Filter>
</ClCompile>
<ClCompile Include="CDeBoxTria.cpp">
<Filter>File di origine\GeoCollision</Filter>
</ClCompile>
<ClCompile Include="CAvSimpleSurfFrMove.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="IntersSurfTmSurfTm.cpp">
<Filter>File di origine\GeoInters</Filter>
@@ -400,19 +394,19 @@
<Filter>File di origine\Geo</Filter>
</ClCompile>
<ClCompile Include="CDeCylTria.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeBoxClosedSurfTm.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeCylClosedSurfTm.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeSpheTria.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeSpheClosedSurfTm.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="SurfBezier.cpp">
<Filter>File di origine\Geo</Filter>
@@ -430,34 +424,34 @@
<Filter>File di origine\GeoDist</Filter>
</ClCompile>
<ClCompile Include="CDeTriaTria.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeConeTria.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeUtility.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeClosedSurfTmClosedSurfTm.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeConeFrustumClosedSurfTm.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeConeFrustumTria.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeConvexTorusClosedSurfTm.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeConvexTorusTria.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeRectPrismoidClosedSurfTm.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="CDeRectPrismoidTria.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="SurfTriMeshUtilities.cpp">
<Filter>File di origine\Geo</Filter>
@@ -469,7 +463,7 @@
<Filter>File di origine\Base</Filter>
</ClCompile>
<ClCompile Include="CDeCapsTria.cpp">
<Filter>File di origine\GeoCollision</Filter>
<Filter>File di origine\GeoCollisionDetection</Filter>
</ClCompile>
<ClCompile Include="Circle2P.cpp">
<Filter>File di origine\GeoCreate</Filter>
@@ -510,6 +504,27 @@
<ClCompile Include="PolygonElevation.cpp">
<Filter>File di origine\GeoElevation</Filter>
</ClCompile>
<ClCompile Include="IntersCurveSurfTm.cpp">
<Filter>File di origine\GeoInters</Filter>
</ClCompile>
<ClCompile Include="CAvSimpleSurfFrMove.cpp">
<Filter>File di origine\GeoCollisionAvoid</Filter>
</ClCompile>
<ClCompile Include="CAvToolSurfTm.cpp">
<Filter>File di origine\GeoCollisionAvoid</Filter>
</ClCompile>
<ClCompile Include="CAvToolTriangle.cpp">
<Filter>File di origine\GeoCollisionAvoid</Filter>
</ClCompile>
<ClCompile Include="IntersLineVolZmap.cpp">
<Filter>File di origine\GeoInters</Filter>
</ClCompile>
<ClCompile Include="IntersPlaneVolZmap.cpp">
<Filter>File di origine\GeoInters</Filter>
</ClCompile>
<ClCompile Include="RotationMinimizeFrame.cpp">
<Filter>File di origine\Geo</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@@ -1169,6 +1184,18 @@
<ClInclude Include="Voronoi.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="RotationMinimizeFrame.h">
<Filter>File di intestazione</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="EgtGeomKernel.rc">
+223
View File
@@ -0,0 +1,223 @@
//----------------------------------------------------------------------------
// EgalTech 2024-2024
//----------------------------------------------------------------------------
// File : IntersCurveSurfTm.cpp Data : 23.02.24 Versione : 2.6b4
// Contenuto : Implementazione della intersezione curva/superficie trimesh.
//
//
//
// Modifiche : 23.02.24 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkIntersLineTria.h"
#include "/EgtDev/Include/EGkIntersCurveSurfTm.h"
using namespace std ;
//----------------------------------------------------------------------------
static void
UpdateInfoIntersCurveSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen, double dUs, double dUe,
int nT, const Triangle3d& Tria, ICSIVECTOR& vInfo)
{
Point3d ptInt, ptInt2 ;
int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2, true) ;
if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) {
double dU = dUs + ( ptInt - ptL) * vtDir / dLen * ( dUe - dUs) ;
double dCosDN = vtDir * Tria.GetN() ;
vInfo.emplace_back( nRes, dU, nT, dCosDN, ptInt) ;
}
else if ( nRes == ILTT_SEGM || nRes == ILTT_SEGM_ON_EDGE) {
double dU = dUs + ( ptInt - ptL) * vtDir / dLen * ( dUe - dUs) ;
double dU2 = dUs + ( ptInt2 - ptL) * vtDir / dLen * ( dUe - dUs) ;
double dCosDN = vtDir * Tria.GetN() ;
vInfo.emplace_back( nRes, dU, dU2, nT, dCosDN, ptInt, ptInt2) ;
}
}
//----------------------------------------------------------------------------
static void
OrderInfoIntersCurveSurfTm( ICSIVECTOR& vInfo)
{
// se non trovati, esco
if ( vInfo.size() == 0)
return ;
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
sort( vInfo.begin(), vInfo.end(),
[]( const IntCrvStmInfo& a, const IntCrvStmInfo& b)
{ double dUa = ( ( a.nILTT == ILTT_SEGM || a.nILTT == ILTT_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ;
double dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
return ( dUa < dUb) ; }) ;
}
//----------------------------------------------------------------------------
// Intersezione di una curva con una superficie TriMesh
//----------------------------------------------------------------------------
bool
IntersCurveSurfTm( const ICurve& Curve, const ISurfTriMesh& Stm, double dLinTol, ICSIVECTOR& vInfo)
{
// verifico i parametri ricevuti
if ( & Curve == nullptr || &Stm == nullptr || &vInfo == nullptr)
return false ;
dLinTol = max( dLinTol, EPS_SMALL) ;
vInfo.clear() ;
// approssimo la curva con una spezzata
PolyLine PL ;
if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, ICurve::APL_SPECIAL, PL))
return false ;
// per ogni segmento dell'approssimante cerco l'intersezione con la superficie
double dParS, dParE ;
Point3d ptStart, ptEnd ;
bool bFound = PL.GetFirstULine( &dParS, &ptStart, &dParE, &ptEnd) ;
while ( bFound) {
Vector3d vtDir = ptEnd - ptStart ;
double dLen = vtDir.Len() ;
if ( dLen > EPS_SMALL) {
vtDir /= dLen ;
// cerco i triangoli intersecati dal segmento
const double BOX_STEP = 10 ;
int nStep = int( ceil( dLen / BOX_STEP)) ;
Vector3d vtStep = dLen / nStep * vtDir ;
INTVECTOR vPrevT ;
for ( int i = 0 ; i < nStep ; ++ i) {
BBox3d b3Box( ptStart + i * vtStep, ptStart + ( i + 1) * vtStep) ;
INTVECTOR vT ;
if ( Stm.GetAllTriaOverlapBox( b3Box, vT)) {
for ( auto nT : vT) {
// se triangolo non ancora intersecato
if ( find( vPrevT.begin(), vPrevT.end(), nT) == vPrevT.end()) {
vPrevT.emplace_back( nT) ;
Triangle3d Tria ;
Stm.GetTriangle( nT, Tria) ;
// aggiorno info con intersezione
UpdateInfoIntersCurveSurfTm( ptStart, vtDir, dLen, dParS, dParE, nT, Tria, vInfo) ;
}
}
}
}
}
// passo al segmento successivo
bFound = PL.GetNextULine( &dParS, &ptStart, &dParE, &ptEnd) ;
}
// ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea
OrderInfoIntersCurveSurfTm( vInfo) ;
return true ;
}
//----------------------------------------------------------------------------
bool
IntersCurveSurfTmExt( const ICurve& Curve, const ISurfTriMesh& Stm, double dLinTol, INTDBLVECTOR& vInters)
{
ICSIVECTOR vInfo ;
vInters.clear() ;
return ( IntersCurveSurfTm( Curve, Stm, dLinTol, vInfo) && FilterCurveSurfTmInters( Curve, vInfo, vInters)) ;
}
//----------------------------------------------------------------------------
bool
FilterCurveSurfTmInters( const ICurve& Curve, const ICSIVECTOR& vInfo, INTDBLVECTOR& vInters)
{
// verifico i parametri ricevuti
if ( & Curve == nullptr || &vInfo == nullptr || &vInters == nullptr)
return false ;
vInters.clear() ;
// info sulla curva
bool bClosedCrv = Curve.IsClosed() ;
double dParSCrv, dParECrv ;
Curve.GetDomain( dParSCrv, dParECrv) ;
// ciclo sulle intersezioni
for ( const auto& Info : vInfo) {
// se intersezione puntuale
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
int nFlag = CSIT_NONE ;
if ( Info.dCosDN > EPS_ZERO)
nFlag = CSIT_IN_OUT ;
else if ( Info.dCosDN < -EPS_ZERO)
nFlag = CSIT_OUT_IN ;
vInters.emplace_back( nFlag, Info.dU) ;
}
// se altrimenti intersezione con coincidenza
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
vInters.emplace_back( CSIT_IN_ON, Info.dU) ;
vInters.emplace_back( CSIT_ON_IN, Info.dU2) ;
}
}
// elimino intersezioni ripetute
int nStart = ( bClosedCrv ? 0 : 1) ;
for ( int j = nStart ; j < int( vInters.size()) ; ) {
// intersezione precedente
int i = ( j > 0 ? j - 1 : int( vInters.size()) - 1) ;
// se hanno lo stesso parametro
if ( abs( vInters[i].second - vInters[j].second) < EPS_PARAM ||
( bClosedCrv && abs( vInters[i].second - dParECrv) < EPS_PARAM && abs( vInters[j].second - dParSCrv) < EPS_PARAM)) {
// flag per eseguita cancellazione
bool bSomeErased = false ;
// se sono entrambe entranti o uscenti, elimino la seconda
if ( ( vInters[i].first == CSIT_OUT_IN && vInters[j].first == CSIT_OUT_IN) ||
( vInters[i].first == CSIT_IN_OUT && vInters[j].first == CSIT_IN_OUT)) {
vInters.erase( vInters.begin() + j) ;
bSomeErased = true ;
}
// se una entrante e l'altra uscente, cambio in touch da fuori ed elimino la seconda
else if ( vInters[i].first == CSIT_OUT_IN && vInters[j].first == CSIT_IN_OUT) {
vInters[i].first = CSIT_OUT_OUT ;
vInters.erase( vInters.begin() + j) ;
bSomeErased = true ;
}
// se una uscente e l'altra entrante, cambio in touch da dentro ed elimino la seconda
else if ( vInters[i].first == CSIT_IN_OUT && vInters[j].first == CSIT_OUT_IN) {
vInters[i].first = CSIT_IN_IN ;
vInters.erase( vInters.begin() + j) ;
bSomeErased = true ;
}
// se una touch da fuori o da dentro e l'altra entrante o uscente, elimino la prima
else if ( ( vInters[i].first == CSIT_OUT_OUT || vInters[i].first == CSIT_IN_IN) &&
( vInters[j].first == CSIT_OUT_IN || vInters[j].first == CSIT_IN_OUT)) {
vInters.erase( vInters.begin() + i) ;
bSomeErased = true ;
}
// se una entrante o uscente e l'altra touch da fuori o da dentro, elimino la seconda
else if ( ( vInters[i].first == CSIT_OUT_IN || vInters[i].first == CSIT_IN_OUT) &&
( vInters[j].first == CSIT_OUT_OUT || vInters[j].first == CSIT_IN_IN)) {
vInters.erase( vInters.begin() + j) ;
bSomeErased = true ;
}
// se una puntuale e l'altra inizio di coincidenza, elimino la prima
else if ( ( vInters[i].first == CSIT_OUT_IN || vInters[i].first == CSIT_IN_OUT || vInters[i].first == CSIT_NONE) &&
( vInters[j].first == CSIT_IN_ON || vInters[j].first == CSIT_OUT_ON)) {
vInters[j].first = ( vInters[i].first == CSIT_IN_OUT ? CSIT_IN_ON : CSIT_OUT_ON) ;
vInters.erase( vInters.begin() + i) ;
bSomeErased = true ;
}
// se una fine di coincidenza e l'altra puntuale, elimino la seconda
else if ( ( vInters[i].first == CSIT_ON_IN || vInters[i].first == CSIT_ON_OUT) &&
( vInters[j].first == CSIT_OUT_IN || vInters[j].first == CSIT_IN_OUT || vInters[j].first == CSIT_NONE)) {
vInters[i].first = ( vInters[j].first == CSIT_IN_OUT ? CSIT_ON_OUT : CSIT_ON_IN) ;
vInters.erase( vInters.begin() + j) ;
bSomeErased = true ;
}
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
else if ( ( vInters[i].first == CSIT_ON_IN || vInters[i].first == CSIT_ON_OUT) &&
( vInters[j].first == CSIT_IN_ON || vInters[j].first == CSIT_OUT_ON)) {
vInters.erase( vInters.begin() + j) ;
vInters.erase( vInters.begin() + ( j > 0 ? i : i - 1)) ;
bSomeErased = true ;
}
if ( bSomeErased) {
if ( j > 0)
-- j ;
continue ;
}
}
// passo alla successiva
++ j ;
}
return true ;
}
+1 -1
View File
@@ -22,7 +22,7 @@ using namespace std ;
//----------------------------------------------------------------------------
// Linea e box allineato assi devono essere nel medesimo sistema di riferimento.
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
// In caso di intersezione viene restituito true e i parametri lunghezza in dU1 e dU2.
//----------------------------------------------------------------------------
bool
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
+1 -1
View File
@@ -17,7 +17,7 @@
//----------------------------------------------------------------------------
// Linea e box allineato agli assi sono nel medesimo riferimento.
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
// Con intersezione viene restituito true e i parametri lunghezza in dU1 e dU2.
//----------------------------------------------------------------------------
bool
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
+70 -5
View File
@@ -21,7 +21,7 @@
using namespace std ;
//----------------------------------------------------------------------------
void
static void
UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen,
int nT, const Triangle3d& Tria, ILSIVECTOR& vInfo, bool bFinite)
{
@@ -41,7 +41,7 @@ UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dL
}
//----------------------------------------------------------------------------
void
static void
OrderInfoIntersLineSurfTm( ILSIVECTOR& vInfo)
{
// se non trovati, esco
@@ -81,7 +81,7 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
// lo ingrandisco per non avere problemi con faccia piana su piani canonici
b3Stm.Expand( 10 * EPS_SMALL) ;
double dU1, dU2 ;
if ( ! IntersLineBox( ptL, vtL, b3Stm.GetMin() , b3Stm.GetMax(), dU1, dU2))
if ( ! IntersLineBox( ptL, vtDir, b3Stm.GetMin() , b3Stm.GetMax(), dU1, dU2))
return true ;
if ( bFinite) {
dU1 = max( dU1, 0.) ;
@@ -89,12 +89,12 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
if ( dU2 - dU1 < EPS_SMALL)
return true ;
}
Point3d ptStart = ptL + dU1 * vtL ;
Point3d ptStart = ptL + dU1 * vtDir ;
double dLenEff = dU2 - dU1 ;
// cerco i triangoli intersecati dalla linea
const double BOX_STEP = 10 ;
int nStep = int( ceil( dLenEff / BOX_STEP)) ;
Vector3d vtStep = dLenEff / nStep * vtL ;
Vector3d vtStep = dLenEff / nStep * vtDir ;
INTVECTOR vPrevT ;
for ( int i = 0 ; i < nStep ; ++ i) {
BBox3d b3Box( ptStart + i * vtStep, ptStart + ( i + 1) * vtStep) ;
@@ -189,3 +189,68 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
return true ;
}
//----------------------------------------------------------------------------
bool
FilterLineSurfTmInters( const ILSIVECTOR& vInfo, INTDBLVECTOR& vInters)
{
// ciclo sulle intersezioni
for ( const auto& Info : vInfo) {
// se intersezione puntuale
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
int nFlag = LST_TOUCH ;
if ( Info.dCosDN > EPS_ZERO)
nFlag = LST_OUT ;
else if ( Info.dCosDN < -EPS_ZERO)
nFlag = LST_IN ;
vInters.emplace_back( nFlag, Info.dU) ;
}
// se altrimenti intersezione con coincidenza
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
vInters.emplace_back( LST_TG_INI, Info.dU) ;
vInters.emplace_back( LST_TG_FIN, Info.dU2) ;
}
}
// elimino intersezioni ripetute
for ( size_t j = 1 ; j < vInters.size() ; ) {
// intersezione precedente
size_t i = j - 1 ;
// se hanno lo stesso parametro
if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
// se sono entrambe entranti o uscenti, elimino la seconda
if ( ( vInters[i].first == LST_IN && vInters[j].first == LST_IN) ||
( vInters[i].first == LST_OUT && vInters[j].first == LST_OUT)) {
vInters.erase( vInters.begin() + j) ;
continue ;
}
// se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
else if ( ( vInters[i].first == LST_IN && vInters[j].first == LST_OUT) ||
( vInters[i].first == LST_OUT && vInters[j].first == LST_IN)) {
vInters[i].first = LST_TOUCH ;
vInters.erase( vInters.begin() + j) ;
continue ;
}
// se una puntuale e l'altra inizio di coincidenza, elimino la prima
else if ( ( vInters[i].first == LST_IN || vInters[i].first == LST_OUT || vInters[i].first == LST_TOUCH) && vInters[j].first == LST_TG_INI) {
vInters.erase( vInters.begin() + i) ;
continue ;
}
// se una fine di coincidenza e l'altra puntuale, elimino la seconda
else if ( vInters[i].first == LST_TG_FIN && ( vInters[j].first == LST_IN || vInters[j].first == LST_OUT || vInters[j].first == LST_TOUCH)) {
vInters.erase( vInters.begin() + j) ;
continue ;
}
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
else if ( i > 0 && vInters[i].first == LST_TG_FIN && vInters[j].first == LST_TG_INI) {
vInters.erase( vInters.begin() + j) ;
vInters.erase( vInters.begin() + i) ;
-- j ;
continue ;
}
}
// passo alla successiva
++ j ;
}
return true ;
}
+106
View File
@@ -0,0 +1,106 @@
//----------------------------------------------------------------------------
// EgalTech 2024-2024
//----------------------------------------------------------------------------
// File : IntersLineVolZmap.cpp Data : 22.02.24 Versione : 2.6b4
// Contenuto : Implementazione della intersezione linea/VolZmap.
//
//
//
// Modifiche : 22.02.24 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "VolZmap.h"
#include "/EgtDev/Include/EGkIntersLineVolZmap.h"
using namespace std ;
//----------------------------------------------------------------------------
// Intersezione di una linea con la superficie di un solido VolZmap
//----------------------------------------------------------------------------
bool
IntersLineVolZmap( const Point3d& ptL, const Vector3d& vtL, const IVolZmap& Vzm, ILZIVECTOR& vInfo)
{
// verifico linea
Vector3d vtDir = vtL ;
if ( ! vtDir.Normalize( EPS_ZERO))
return false ;
// verifico volume
const VolZmap* pVzm = GetBasicVolZmap( &Vzm) ;
if ( pVzm == nullptr)
return false ;
// verifico parametro di ritorno
if ( &vInfo == nullptr)
return false ;
// eseguo intersezione
return pVzm->GetLineIntersection( ptL, vtL, vInfo) ;
}
//----------------------------------------------------------------------------
bool
FilterLineVolZmapInters( const ILZIVECTOR& vInfo, INTDBLVECTOR& vInters)
{
// ciclo sulle intersezioni
for ( const auto& Info : vInfo) {
// se intersezione puntuale
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
int nFlag = LZT_TOUCH ;
if ( Info.dCosDN > EPS_ZERO)
nFlag = LZT_OUT ;
else if ( Info.dCosDN < -EPS_ZERO)
nFlag = LZT_IN ;
vInters.emplace_back( nFlag, Info.dU) ;
}
// se altrimenti intersezione con coincidenza
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
vInters.emplace_back( LZT_TG_INI, Info.dU) ;
vInters.emplace_back( LZT_TG_FIN, Info.dU2) ;
}
}
// elimino intersezioni ripetute
for ( size_t j = 1 ; j < vInters.size() ; ) {
// intersezione precedente
size_t i = j - 1 ;
// se hanno lo stesso parametro
if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
// se sono entrambe entranti o uscenti, elimino la seconda
if ( ( vInters[i].first == LZT_IN && vInters[j].first == LZT_IN) ||
( vInters[i].first == LZT_OUT && vInters[j].first == LZT_OUT)) {
vInters.erase( vInters.begin() + j) ;
continue ;
}
// se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
else if ( ( vInters[i].first == LZT_IN && vInters[j].first == LZT_OUT) ||
( vInters[i].first == LZT_OUT && vInters[j].first == LZT_IN)) {
vInters[i].first = LZT_TOUCH ;
vInters.erase( vInters.begin() + j) ;
continue ;
}
// se una puntuale e l'altra inizio di coincidenza, elimino la prima
else if ( ( vInters[i].first == LZT_IN || vInters[i].first == LZT_OUT || vInters[i].first == LZT_TOUCH) && vInters[j].first == LZT_TG_INI) {
vInters.erase( vInters.begin() + i) ;
continue ;
}
// se una fine di coincidenza e l'altra puntuale, elimino la seconda
else if ( vInters[i].first == LZT_TG_FIN && ( vInters[j].first == LZT_IN || vInters[j].first == LZT_OUT || vInters[j].first == LZT_TOUCH)) {
vInters.erase( vInters.begin() + j) ;
continue ;
}
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
else if ( i > 0 && vInters[i].first == LZT_TG_FIN && vInters[j].first == LZT_TG_INI) {
vInters.erase( vInters.begin() + j) ;
vInters.erase( vInters.begin() + i) ;
-- j ;
continue ;
}
}
// passo alla successiva
++ j ;
}
return true ;
}
+37
View File
@@ -0,0 +1,37 @@
//----------------------------------------------------------------------------
// EgalTech 2024-2024
//----------------------------------------------------------------------------
// File : IntersPlaneVolZmap.cpp Data : 22.02.24 Versione : 2.6b4
// Contenuto : Implementazione della intersezione piano/VolZmap.
//
//
//
// Modifiche : 22.02.24 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "VolZmap.h"
#include "/EgtDev/Include/EGkIntersPlaneVolZmap.h"
using namespace std ;
//----------------------------------------------------------------------------
// Intersezione di unpiano con la superficie di un solido VolZmap
//----------------------------------------------------------------------------
bool
IntersPlaneVolZmap( const Plane3d& plPlane, const IVolZmap& Vzm, ICURVEPOVECTOR& vpLoop)
{
// verifico volume
const VolZmap* pVzm = GetBasicVolZmap( &Vzm) ;
if ( pVzm == nullptr)
return false ;
// verifico parametro di ritorno
if ( &vpLoop == nullptr)
return false ;
// eseguo intersezione
return pVzm->GetPlaneIntersection( plPlane, vpLoop) ;
}
+76 -55
View File
@@ -721,15 +721,42 @@ PolyLine::AdjustForMaxSegmentLen( double dMaxLen)
return true ;
}
//----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
static bool
PointsInTolerance( const PNTVECTOR& vRPT, const Point3d& ptP1, const Point3d& ptP2, double dSqTol)
DouglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const int nIndStart,
const int nIndEnd, INTVECTOR& vInd)
{
for ( const auto& ptQ : vRPT) {
double dSqDist ;
if ( ! DistPointLine( ptQ, ptP1, ptP2).GetSqDist( dSqDist) || dSqDist > dSqTol)
// se indici uguali, ritorno
if ( nIndStart == nIndEnd)
return true ;
// distanza massima e indice del punto associato
double dMaxSqDist = 0. ;
int nMaxInd = 0 ;
// scorro i punti intermedi tra nIndStart e nIndEnd
for ( int i = nIndStart + 1 ; i < nIndEnd ; ++ i) {
double dCurrSqDist = 0. ;
// distanza tra il punto attuale e la retta tra i punti di indici nIndStart ed nIndEnd
DistPointLine DPL( vPtU[i].first, vPtU[nIndStart].first, vPtU[nIndEnd].first) ;
if ( DPL.GetSqDist( dCurrSqDist) && dCurrSqDist > dMaxSqDist) {
// aggiorno i parametri
dMaxSqDist = dCurrSqDist ;
nMaxInd = i ;
}
}
// se la distanza massima trovata è sopra la tolleranza, allora controllo la parte di PolyLine tra
// (nIndStart, nMaxInd) e quella tra (nMaxInd, nIndEnd)
if ( dMaxSqDist > dSqTol) {
// inserisco il punto
vInd.push_back( nMaxInd) ;
// split
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nIndStart, nMaxInd, vInd) ||
! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, nIndEnd, vInd))
return false ;
}
return true ;
}
@@ -743,59 +770,53 @@ PolyLine::RemoveAlignedPoints( double dToler)
// controllo minimo valore di tolleranza
dToler = max( dToler, LIN_TOL_MIN) ;
double dSqTol = dToler * dToler ;
// si analizza la distanza di un punto dal segmento che unisce precedente e successivo
// punto precedente
auto precP = m_lUPoints.begin() ;
// punto corrente
auto currP = next( precP) ;
// punto successivo
auto nextP = next( currP) ;
// lista dei punti appena rimossi
PNTVECTOR vRPT ; vRPT.reserve( 20) ;
// mentre esiste un successivo
while ( nextP != m_lUPoints.end()) {
// distanza del punto corrente dal segmento che unisce gli adiacenti
DistPointLine dPL( currP->first, precP->first, nextP->first) ;
double dSqDist ;
// se da eliminare
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vRPT, precP->first, nextP->first, dSqTol)) {
// aggiungo il punto nella lista dei rimossi
vRPT.emplace_back( currP->first) ;
// elimino il punto
m_lUPoints.erase( currP) ;
// avanzo con corrente e successivo
currP = nextP ;
++ nextP ;
}
// altrimenti da tenere
else {
// cancello la lista dei rimossi
vRPT.clear() ;
// avanzo il terzetto di uno step
precP = currP ;
currP = nextP ;
++ nextP ;
}
// vettore contenente i punti della polyline
PNTUVECTOR vPtU ; vPtU.reserve( m_lUPoints.size()) ;
for ( const auto& ptCurr : m_lUPoints)
vPtU.emplace_back( ptCurr) ;
// vettore indici dei punti rimanenti
INTVECTOR vInd ; vInd.reserve( vPtU.size()) ;
// se aperta
if ( ! IsClosed()) {
// considero tutti i punti della PolyLine
vInd.push_back( 0) ;
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vInd))
return false ;
vInd.push_back( vPtU.size() - 1) ;
}
// se curva chiusa con almeno 4 punti, devo analizzare il terzetto attorno alla chiusura
if ( IsClosed() && m_lUPoints.size() >= 4) {
// precP e currP sono già corretti
// il primo punto ripete l'ultimo (geometricamente coincide con currP)
auto firstP = m_lUPoints.begin() ;
// questo è il vero successivo
nextP = next( firstP) ;
// distanza del punto corrente dal segmento che unisce gli adiacenti
DistPointLine dPL( currP->first, precP->first, nextP->first) ;
double dSqDist ;
// se da eliminare
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vRPT, precP->first, nextP->first, dSqTol)) {
// faccio coincidere il primo punto con il precedente
firstP->first = precP->first ;
// elimino il punto corrente
m_lUPoints.erase( currP) ;
// altrimenti chiusa
else {
// cerco il punto più distante dal primo
double dMaxDist = 0. ;
int nMaxInd = 0 ;
for ( int i = 1 ; i < int( vPtU.size()) ; ++ i) {
double dCurrDist = Dist( vPtU[0].first, vPtU[i].first) ;
if ( dCurrDist > dMaxDist) {
dMaxDist = dCurrDist ;
nMaxInd = i ;
}
}
// recupero due PolyLine di approssimazione
vInd.push_back( 0) ;
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, nMaxInd, vInd))
return false ;
vInd.push_back( nMaxInd) ;
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vInd))
return false ;
vInd.push_back( vPtU.size() - 1) ;
}
// ordino in senso crescente
sort( vInd.begin(), vInd.end()) ;
// rimetto in lista i soli punti rimasti
m_lUPoints.clear() ;
for ( auto Ind : vInd)
m_lUPoints.push_back( vPtU[Ind]) ;
return true ;
}
+265
View File
@@ -0,0 +1,265 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2024
//----------------------------------------------------------------------------
// File : RotationMinimizeFrame.cpp Data : 05.03.24 Versione : 2.6c1
// Contenuto : Classe per RotationMinimizeFrame
//
//
//
// Modifiche : 05.03.24 RE Creazione modulo.
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "RotationMinimizeFrame.h"
#include "GeoConst.h"
using namespace std ;
RotationMinimizeFrame::RotationMinimizeFrame( const ICurve* pCrv, const Frame3d& fr_Start)
{
// assegno i parametri
m_pCrv = pCrv->Clone() ;
m_Frame0 = fr_Start ;
}
//----------------------------------------------------------------------------
RotationMinimizeFrame::~RotationMinimizeFrame( void)
{
Clear() ;
}
//----------------------------------------------------------------------------
bool
RotationMinimizeFrame::Clear( void)
{
// pulizia della curva
if ( m_pCrv != nullptr)
delete m_pCrv ;
m_pCrv = nullptr ;
// reset del frame di partenza
m_Frame0.Reset() ;
return true ;
}
//----------------------------------------------------------------------------
bool
RotationMinimizeFrame::IsValid()
{
// controllo validità della curva
if ( m_pCrv == nullptr || ! m_pCrv->IsValid())
return false ;
// controllo del frame iniziale
if ( ! m_Frame0.IsValid())
return false ;
// controllo che l'origine del frame sia sulla curva e che l'asse Z sia tangente alla curva
Point3d ptS ;
Vector3d vtZ ;
if ( ! m_pCrv->GetPointD1D2( 0., ICurve::FROM_MINUS, ptS, &vtZ) ||
! vtZ.Normalize() ||
! AreSamePointApprox( ptS, m_Frame0.Orig()) ||
! AreSameVectorEpsilon( vtZ, m_Frame0.VersZ(), 5 * EPS_SMALL))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
RotationMinimizeFrame::GetFrameAtLength( const Frame3d& frAct, const double dLenNext, Frame3d& frNext)
{
/*
Double Reflection
Computation of Rotation Minimizing Frame in Computer Graphics
Wenping Wang Bert Juttler Dayue Zheng Yang Liu
*/
// ricavo i parametri dal frame
if ( ! frAct.IsValid())
return false ;
// origine del frame e versori ( ptAct, [ vt_r, vt_s, vt_t])
Point3d ptCurr = frAct.Orig() ;
Vector3d vt_r = frAct.VersX() ;
Vector3d vt_t = frAct.VersZ() ;
// ( vt_s è implicito )
double dUNext ; // parametro sulla curva nello step successivo
Point3d ptNext ; // punto sulla curva allo step successivo
// parametro (i+1)-esimo sulla curva
if ( ! m_pCrv->GetParamAtLength( dLenNext, dUNext))
return false ;
// punto (i+1)-esimo sulla curva e suo vettore tangente
Vector3d vt_t_next ;
if ( ! m_pCrv->GetPointD1D2( dUNext, ICurve::FROM_MINUS, ptNext, &vt_t_next) ||
! vt_t_next.IsValid() || ! vt_t_next.Normalize()) // versore tangente
return false ;
// controllo per casi degeneri
if ( AreSamePointEpsilon( ptCurr, ptNext, EPS_ZERO) || // non esiste il piano R1
abs(( ptNext - ptCurr) * ( vt_t_next + vt_t)) < EPS_ZERO) // non esiste il piano R2
return false ;
// ricavo il vettore di riflessione rispetto al piano R1
Vector3d vR1_norm = ptNext - ptCurr ;
if ( ! vR1_norm.IsValid())
return false ;
// parametro di riflessione per R1
double dPar1 = vR1_norm * vR1_norm ;
// riflessione rispetto al piano R1 ( sistema sinistrorso L )
Vector3d vt_r_L = vt_r - ( 2 / dPar1) * ( vR1_norm * vt_r) * vR1_norm ;
Vector3d vt_t_L = vt_t - ( 2 / dPar1) * ( vR1_norm * vt_t) * vR1_norm ;
// ricavo il vettore di riflessione rispetto al piano R1
Vector3d vR2_norm = vt_t_next - vt_t_L ;
if ( ! vR2_norm.IsValid())
return false ;
// parametro di riflessione per R2
double dPar2 = vR2_norm * vR2_norm ;
// versore r del nuovo frame
Vector3d vt_r_next = vt_r_L - ( 2 / dPar2) * ( vR2_norm * vt_r_L) * vR2_norm ;
// versore t del nuovo frame
Vector3d vt_s_next = vt_t_next ^ vt_r_next ;
// imposto il nuovo frame
frNext.Set( ptNext, vt_r_next, vt_s_next, vt_t_next) ;
if ( ! frNext.IsValid()) { // il frame potrebbe non essere nelle tolleranze...
// ... sistemo ricavando il versore "s" mediante "t" ed "r" ...
frNext.Set( ptNext, vt_t_next, vt_r_next) ;
if ( ! frNext.IsValid())
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
RotationMinimizeFrame::GetFramesByStep( FRAME3DVECTOR& vRMFrames, double dStep, bool bUniform)
{
// controllo sullo step
dStep = max( 10 * EPS_SMALL, dStep) ;
// controllo validità
if ( ! IsValid()) {
Clear() ;
return false ;
}
// calcolo lunghezza della curva
double dLen = 0. ;
if ( ! m_pCrv->GetLength( dLen))
return false ;
// in prima posizione viene inserito il frame iniziale
vRMFrames.push_back( m_Frame0) ;
// ricavo il numero degli step
int nStep = int( ceil( dLen / dStep)) ;
if ( nStep == 0) // se non ho step allora serve sono il frame iniziale
return true ;
// lunghezza della curva identificata dal punto successivo
double dLenNext ;
// step corrente
double dMyStep = dStep ;
if ( bUniform)
dMyStep = dLen / nStep ;
// ciclo sugli step in cui la curva è suddivisa
for ( int i = 0 ; i < nStep ; ++ i) {
// ricavo la lunghezza della curva relativo allo step (i+1)-esimo
dLenNext = min( dLen - 10 * EPS_SMALL, ( i + 1) * dMyStep) ;
// ricavo il frame alla lunghezza calcolata
Frame3d frNext ;
if ( ! GetFrameAtLength( vRMFrames[i], dLenNext, frNext))
return false ;
// aggiornamento vettore dei frame
vRMFrames.push_back( frNext) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
RotationMinimizeFrame::GetFramesBySplit( FRAME3DVECTOR& vRMFrames, int nIntervals)
{
// controllo sul numero di intervalli
nIntervals = max( 1, nIntervals) ;
// ricavo lo step associato
double dLen = 0 ;
if ( ! m_pCrv->GetLength( dLen))
return false ;
// ricavo lo step associato
double dStep = dLen / nIntervals ;
return GetFramesByStep( vRMFrames, dStep) ;
}
//----------------------------------------------------------------------------
bool
RotationMinimizeFrame::GetFramesByTollerance( FRAME3DVECTOR& vRMFrames, double dTol)
{
// controllo sulla tolleranza
dTol = max( EPS_SMALL, dTol) ;
// controllo validità
if ( ! IsValid()) {
Clear() ;
return false ;
}
// ricavo la PolyLine associata alla curva mediante tale tolleranza
PolyLine PL ;
if ( ! m_pCrv->ApproxWithLines( dTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
return false ;
// ricavo la lunghezza della curva
double dCrvLen = 0 ;
if ( ! m_pCrv->GetLength( dCrvLen))
return false ;
// devo calcolare il RMF su ogni punto ricavato dall'approssimazione
Point3d ptCurr ;
bool bPoint = PL.GetFirstPoint( ptCurr) ;
bool bFirst = true ;
while ( bPoint) {
if ( bFirst) {
// in prima posizione viene inserito il frame iniziale
vRMFrames.push_back( m_Frame0) ;
bFirst = false ;
}
else {
// ricavo la lunghezza della curva al punto corrente
double dLen = 0. ;
if ( ! m_pCrv->GetLengthAtPoint( ptCurr, dLen))
return false ;
// per sicurezza controllo che sia minore della lunghezza complessiva
dLen = min( dCrvLen - 10 * EPS_SMALL , dLen) ;
// ricavo il Frame associato a tale lunghezza
Frame3d frNext ;
if ( ! GetFrameAtLength( vRMFrames.back(), dLen, frNext))
return false ;
vRMFrames.emplace_back( frNext) ;
}
// passo al punto successivo
bPoint = PL.GetNextPoint( ptCurr) ;
}
return true ;
}
+44
View File
@@ -0,0 +1,44 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2024
//----------------------------------------------------------------------------
// File : RotationMinimizeFrame.h Data : 05.03.24 Versione : 2.6c1
// Contenuto : Dichiarazione della classe RotationMinimizeFrame
//
//
//
// Modifiche : 05.03.24 RE Creazione modulo.
//
//----------------------------------------------------------------------------
#pragma once
#include "/EgtDev/Include/EGkFrame3d.h"
#include "/EgtDev/Include/EGkCurve.h"
#include <vector>
//----------------------------------------------------------------------------
typedef std::vector<Frame3d> FRAME3DVECTOR ;
//----------------------------------------------------------------------------
class RotationMinimizeFrame
{
public :
RotationMinimizeFrame( const ICurve* pCrv, const Frame3d& fr_Start) ;
~RotationMinimizeFrame( void) ;
public :
bool GetFramesByStep( FRAME3DVECTOR& vRMFrames, double dStep, bool bUniform = false) ;
bool GetFramesBySplit( FRAME3DVECTOR& vRMFrames, int nIntervals) ;
bool GetFramesByTollerance( FRAME3DVECTOR& vRMFrames, double dTol) ;
private :
bool Clear( void) ;
bool IsValid( void) ;
bool GetFrameAtLength( const Frame3d& frAct, const double dLenNext, Frame3d& frNext) ;
private :
ICurve* m_pCrv ; // curva per il calcolo del rotation minimize frame
Frame3d m_Frame0 ; // frame iniziale della curva
} ;
+471 -62
View File
@@ -1,4 +1,4 @@
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : StmFromCurves.cpp Data : 01.02.15 Versione : 1.6b1
@@ -19,10 +19,12 @@
#include "CurveComposite.h"
#include "SurfTriMesh.h"
#include "Voronoi.h"
#include "RotationMinimizeFrame.h"
#include "/EgtDev/Include/EGkOffsetCurve.h"
#include "/EgtDev/Include/EGkStmFromCurves.h"
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
#include <algorithm>
#include <thread>
#include <future>
@@ -110,9 +112,9 @@ GetSurfTriMeshByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSTM) || ! pSTM->CreateByExtrusion( PL, vtExtr))
return nullptr ;
// se da fare, metto i tappi sulle estremità
// se da fare, metto i tappi sulle estremità
if ( bDoCapEnds) {
// creo la prima superficie di estremità
// creo la prima superficie di estremità
SurfTriMesh STM1 ;
if ( ! STM1.CreateByFlatContour( PL))
return nullptr ;
@@ -156,7 +158,7 @@ GetSurfTriMeshByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d&
for ( int i = 0 ; i < int( vPL.size()) ; ++ i)
vPL[i].Invert() ;
}
// creo la prima superficie di estremità
// creo la prima superficie di estremità
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL))
return nullptr ;
@@ -288,7 +290,7 @@ GetSurfTriMeshByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vecto
return nullptr ;
// se richiesti caps
if ( bCapEnds) {
// determino se la sezione è chiusa e piatta
// determino se la sezione è chiusa e piatta
Plane3d plPlane ; double dArea ;
bool bSectClosedFlat = PL.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL) ;
// determino non sia una semplice rivoluzione
@@ -332,7 +334,7 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
return nullptr ;
Vector3d vtNorm = plGuide.GetVersN() ;
// determino se la guida è chiusa
// determino se la guida è chiusa
bool bGuideClosed = pGuide->IsClosed() ;
// curve di offset
OffsetCurve OffsCrvR ;
@@ -373,7 +375,7 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
pSTM->SetSmoothAngle( 20) ;
// se guida aperta e tappi piatti
if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
// verifico che le due estremità siano chiuse e piatte
// verifico che le due estremità siano chiuse e piatte
POLYLINEVECTOR vPL ;
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
return nullptr ;
@@ -452,7 +454,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
Point3d ptCen ;
pGuide->GetStartPoint( ptCen) ;
ptCen -= dDimV / 2 * vtNorm ;
// determino se la guida è chiusa
// determino se la guida è chiusa
bool bGuideClosed = pGuide->IsClosed() ;
// curve di offset
const int NUM_OFFS = 4 ;
@@ -475,7 +477,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
}
}
else {
// se Voronoi non è possibile calcolare gli offset di una stessa curva in parallelo
// se Voronoi non è possibile calcolare gli offset di una stessa curva in parallelo
for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i)
bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ;
}
@@ -552,7 +554,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
StmFromTriangleSoup stmCapSoup ;
if ( ! stmCapSoup.Start( nBuckets))
return nullptr ;
// verifico che le due estremità siano chiuse e piatte
// verifico che le due estremità siano chiuse e piatte
POLYLINEVECTOR vPL ;
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
return nullptr ;
@@ -651,34 +653,450 @@ GetSurfTriMeshRectSwept( double dDimH, double dDimV, double dBevelH, double dBev
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, double dLinTol)
GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, double dLinTol, Vector3d* vtStatic)
{
// verifica parametri
if ( pSect == nullptr || pGuide == nullptr)
return nullptr ;
// calcolo la polilinea che approssima la sezione
PolyLine PL ;
if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
return nullptr ;
// determino se la sezione è chiusa
// determino se la sezione è chiusa
bool bSectClosed = PL.IsClosed() ;
// determino se la guida è chiusa
bool bGuideClosed = pGuide->IsClosed() ;
// definisco la superficie da restituire ( definendo la sua tolleranza )
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSTM))
return nullptr ;
pSTM->SetLinearTolerance( dLinTol) ;
// calcolo punto e versore tangente iniziale
Point3d ptStart ; pGuide->GetStartPoint( ptStart) ;
Vector3d vtStart ; pGuide->GetStartDir( vtStart) ;
// inizializzazione del frame iniziale ( viene definito a seconda dei casi )
Frame3d frStart ;
/* GUIDA PIANA */
// verifico che la linea guida sia piana
Plane3d plGuide ;
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
return nullptr ;
// determino se la guida è chiusa
bool bGuideClosed = pGuide->IsClosed() ;
// riferimento all'inizio della linea guida
Frame3d frStart ;
Point3d ptStart ;
pGuide->GetStartPoint( ptStart) ;
Vector3d vtStart ;
pGuide->GetStartDir( vtStart) ;
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL)) {
/*
La guida non è piana, l'estrusione può essere definita mediante :
( 1) un versore statico
( 2) mediante l'algoritmo del Rotation Minimize Frame
*/
// recupero la sezione dalla PolyLine approssimata come Curva
PtrOwner<CurveComposite> pSecLocApprox( CreateBasicCurveComposite()) ;
if ( IsNull( pSecLocApprox) ||
! pSecLocApprox->FromPolyLine( PL) ||
! pSecLocApprox->IsValid())
return nullptr ;
// recupero il frame iniziale sulla guida ( Origine sul punto iniziale e asse Z tangente )
frStart.Set( ptStart, vtStart) ;
if ( ! frStart.IsValid())
return nullptr ;
// tengo in memoria il frame nel punto iniziale e finale della guida in caso di caps
Frame3d frCaps_start ;
Frame3d frCaps_end ;
if ( vtStatic != nullptr) { // (1) versore statico
// creo il piano di proiezione con normale definita dal vettore
Plane3d plProj ;
plProj.Set( ORIG, *vtStatic) ;
if ( ! plProj.IsValid())
return nullptr ;
// porto la sezione nel frame definito dalla guida, tenendo il versore X del frame nel piano
// definito da vtStatic
Vector3d vtX = vtStart ; // versore tangente alla curva
vtX.Rotate( *vtStatic, 90) ; // ruoto di 90 gradi rispetto a vtStatic
OrthoCompo( vtX, *vtStatic) ; // tengo la componente nel piano
vtX.Normalize() ; // normalizzo
Frame3d frInitial ; frInitial.Set( ptStart, vtStart, vtX) ; // creo il frame
if ( ! frInitial.IsValid())
return nullptr ;
// porto la sezione nel riferimento
pSecLocApprox->ToLoc( frInitial) ;
PL.ToLoc( frInitial) ; //... porto anche la PolyLine del bordo della sezione
// approssimo la guida mediante la tolleranza richiesta
PolyLine PL_G ;
if ( ! pGuide->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL_G))
return nullptr ;
// punto attuale e punto successivo sulla guida su cui definire il frame
Point3d ptCurr, ptSucc ;
if ( ! PL_G.GetFirstPoint( ptCurr))
return nullptr ;
bool bNextPoint = PL_G.GetNextPoint( ptSucc) ;
if ( ! bNextPoint)
return nullptr ;
// parametro attuale e successivo riferito ai punti sulla guida
double dParCurr = 0 ;
double dParSucc ;
// versore attuale e successivo riferito ai punti sulla guida
Vector3d vtTanCurr, vtTanSucc ;
if ( ! pGuide->GetStartDir( vtTanCurr))
return nullptr ;
// frame iniziale e successivo riferito alla curva
Frame3d frCurr, frSucc ;
bool bFirstIter = true ; // per salvare il frame iniziale nel caso di caps
while ( bNextPoint) { // finchè recupero un punto sucessivo...
// recupero il parametro successivo riferito alla guida
if ( ! pGuide->GetParamAtPoint( ptSucc, dParSucc))
return nullptr ;
// recupero il versore tangente riferito al punto successivo sulla guida
if ( ! pGuide->GetPointD1D2( dParSucc, ICurve::FROM_MINUS, ptSucc, &vtTanSucc) ||
! vtTanSucc.Normalize())
return nullptr ;
// creazione del frame nel punto corrente
Vector3d vtX_curr = vtTanCurr ;
vtX_curr.Rotate( *vtStatic, 90) ;
OrthoCompo( vtX_curr, *vtStatic) ;
vtX_curr.Normalize() ;
frCurr.Set( ptCurr, vtTanCurr, vtX_curr) ;
if ( ! frCurr.IsValid())
return nullptr ;
// memorizzo il primo frame di caso di caps
if ( bFirstIter) {
frCaps_start = frCurr ;
bFirstIter = false ;
}
// creazione del frame nel punto successivo
Vector3d vtX_succ = vtTanSucc ;
vtX_succ.Rotate( *vtStatic, 90) ;
OrthoCompo( vtX_curr, *vtStatic) ;
vtX_succ.Normalize() ;
frSucc.Set( ptSucc, vtTanSucc, vtX_succ) ;
if ( ! frSucc.IsValid())
return nullptr ;
frCaps_end = frSucc ; // aggiorno il frame finale ad ogni step
// definisco la sezione allo step corrente
PtrOwner<ICurve> pSecCurr( pSecLocApprox->Clone()) ;
if ( IsNull( pSecCurr) || ! pSecCurr->IsValid())
return nullptr ;
// considero la sezione ( in locale ) come vista dal globale
if ( ! pSecCurr->ToGlob( frCurr))
return nullptr ;
// definisco la sezione allo step successivo
PtrOwner<ICurve> pSecSucc( pSecLocApprox->Clone()) ;
if ( IsNull( pSecSucc) || ! pSecSucc->IsValid())
return nullptr ;
// considero la sezione ( in locale ) come vista dal globale
if ( ! pSecSucc->ToGlob( frSucc))
return nullptr ;
// creo la rigata tra queste due sezioni
PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pSecCurr, pSecSucc, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
if ( IsNull( pSr) || ! pSr->IsValid())
return nullptr ;
// attacco la rigata alla superficie da restituire
pSTM->DoSewing( *pSr) ;
// aggiornamento dei parametri
ptCurr = ptSucc ; // il punto corrente diventa il successivo
bNextPoint = PL_G.GetNextPoint( ptSucc) ; // il successivo lo recupero dalla PolyLine
vtTanCurr = vtTanSucc ; // il versore tangete corrente diventa il successivo
}
// la superficie definita dal RMF è invertita, il versore Z è diretto come la tangente della curva
pSTM->Invert() ;
}
else { // (2) Rotation Minimize Frame
// porto la PolyLine e la curva della sezione nel riferimento nel punto iniziale della guida
pSecLocApprox->ToLoc( frStart) ;
PL.ToLoc( frStart) ;
// calcolo il vettore di Frames campionati lungo la guida mediante la tolleranza definita
RotationMinimizeFrame RMF( pGuide, frStart) ;
FRAME3DVECTOR vRMF ;
if ( ! RMF.GetFramesByTollerance( vRMF, dLinTol) || vRMF.empty())
return nullptr ;
// per ogni RMF calcolato, la sezione va roto-traslata lungo la guida
for ( int i = 0 ; i < int( vRMF.size()) - 1 ; ++ i) {
// definisco la sezione allo step corrente
PtrOwner<ICurve> pSecCurr( pSecLocApprox->Clone()) ;
if ( IsNull( pSecCurr) || ! pSecCurr->IsValid())
return nullptr ;
// considero la sezione ( in locale ) come vista dal globale
if ( ! pSecCurr->ToGlob( vRMF[i]))
return nullptr ;
// definisco la sezione allo step successivo
PtrOwner<ICurve> pSecSucc( pSecLocApprox->Clone()) ;
if ( IsNull( pSecSucc) || ! pSecSucc->IsValid())
return nullptr ;
// considero la sezione ( in locale ) come vista dal globale
if ( ! pSecSucc->ToGlob( vRMF[i+1]))
return nullptr ;
// creo la rigata tra queste due sezioni
PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pSecCurr, pSecSucc, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
if ( IsNull( pSr) || ! pSr->IsValid())
return nullptr ;
// attacco la rigata alla superficie da restituire
pSTM->DoSewing( *pSr) ;
}
// la superficie definita dal RMF è invertita, il versore Z è diretto come la tangente della curva
pSTM->Invert() ;
// assegno frame iniziale e finale per caps
frCaps_start = vRMF[0] ;
frCaps_end = vRMF.back() ;
}
// se richiesti caps e sezione chiusa e guida aperta
// (1) vtStatic, (2) Rotation Minimize Frame
if ( bCapEnds && bSectClosed && ! bGuideClosed) {
// aggiungo il cap sull'inizio ( portandolo nel frame del punto iniziale della guida )
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
return nullptr ;
pSci->ToGlob( frCaps_start) ;
// unisco
pSTM->DoSewing( *pSci) ;
// aggiungo il cap sulla fine ( portandolo nel frame del punto finale della guida )
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
return nullptr ;
pSce->ToGlob( frCaps_end) ;
pSce->Invert() ; // il versore z è definito dalle tangenti alla curva
// unisco
pSTM->DoSewing( *pSce) ;
}
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
double dVol ;
if ( pSTM->GetVolume( dVol) && dVol < 0)
pSTM->Invert() ;
// restituisco la superficie
return Release( pSTM) ;
}
/*
GUIDA PIANA
La guida è piana, l'estrusione viene definita mediante Offset della guida sulla sezione
*/
// il frame iniziale è definito dal versore tangente e dalla normale al piano
// che contiene la guida
Vector3d vtNorm = plGuide.GetVersN() ;
frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
// porto la sezione in questo riferimento e ve la appiattisco
if ( ! PL.ToLoc( frStart) || ! PL.Flatten())
return nullptr ;
// superficie swept
PtrOwner<ICurve> pPrevCrv ;
Point3d ptP ;
bool bPoint = PL.GetFirstPoint( ptP) ;
while ( bPoint) {
// nuova curva ( definita dall'Offset )
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pGuide, ptP.x, ICurve::OFF_FILLET) || OffsCrv.GetCurveCount() == 0)
return nullptr ;
PtrOwner<ICurve> pCurrCrv( OffsCrv.GetLongerCurve()) ;
if ( IsNull( pCurrCrv))
return nullptr ;
pCurrCrv->Translate( ptP.y * frStart.VersY()) ;
// se esiste la curva precedente, costruisco la rigata ( di tipo minima distanza)
if ( ! IsNull( pPrevCrv)) {
PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
if ( IsNull( pSr))
return nullptr ;
// unisco
pSTM->DoSewing( *pSr) ;
}
// salvo la curva come prossima precedente
pPrevCrv.Set( pCurrCrv) ;
// prossimo punto
bPoint = PL.GetNextPoint( ptP) ;
}
// se richiesti caps e sezione chiusa e guida aperta
if ( bCapEnds && bSectClosed && ! bGuideClosed) {
// verifico che le due estremità siano chiuse e piatte
POLYLINEVECTOR vPL ;
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
return nullptr ;
Plane3d plEnds ; double dArea ;
if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
return nullptr ;
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
return nullptr ;
// aggiungo il cap sull'inizio
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
return nullptr ;
pSci->ToGlob( frStart) ;
// unisco
pSTM->DoSewing( *pSci) ;
// riferimento alla fine della linea guida
Frame3d frEnd ;
Point3d ptEnd ;
pGuide->GetEndPoint( ptEnd) ;
Vector3d vtEnd ;
pGuide->GetEndDir( vtEnd) ;
frEnd.Set( ptEnd, -vtEnd, vtEnd ^ vtNorm) ;
// aggiungo il cap sulla fine
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
return nullptr ;
pSce->Invert() ;
pSce->ToGlob( frEnd) ;
// unisco
pSTM->DoSewing( *pSce) ;
}
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
double dVol ;
if ( pSTM->GetVolume( dVol) && dVol < 0)
pSTM->Invert() ;
// restituisco la superficie
return Release( pSTM) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, bool bCapEnds,
double dLinTol, Vector3d* vtStatic)
{
// verifica dei parametri
if ( pSfrSect == nullptr || pGuide == nullptr)
return nullptr ;
// creo la Trimesh da restituire
PtrOwner<ISurfTriMesh> pStmSwept( CreateBasicSurfTriMesh()) ;
if ( IsNull( pStmSwept) || ! pStmSwept->AdjustTopology())
return nullptr ;
StmFromTriangleSoup StmSoup ;
StmSoup.Start() ;
// per ogni loop della superficie, creo una Swept
for ( int c = 0 ; c < pSfrSect->GetChunkCount() ; ++ c) {
for ( int l = 0 ; l < pSfrSect->GetLoopCount( c) ; ++ l) {
// recupero il loop
PtrOwner<ICurve> pCrvLoop( pSfrSect->GetLoop( c, l)) ;
if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid())
return nullptr ;
// creo la Trimesh Swept
PtrOwner<ISurfTriMesh> pStmLoopSwept( GetSurfTriMeshSwept( pCrvLoop, pGuide, false, dLinTol, vtStatic)) ;
if ( IsNull( pStmLoopSwept) || ! pStmLoopSwept->IsValid())
return nullptr ;
// aggiungo la Swept ricavata al risultato finale ( come triangoli )
StmSoup.AddSurfTriMesh( *pStmLoopSwept) ;
}
}
StmSoup.End() ;
if ( ! pStmSwept.Set( StmSoup.GetSurf()) || IsNull( pStmSwept) ||
! pStmSwept->IsValid() || ! pStmSwept->AdjustTopology())
return nullptr ;
// se rischista chiusura...
// NB. Controllo solo che al guida non sia chiusa, la sezione derivando da una Flatregion è chiusa per
// definizione
if ( bCapEnds && ! pGuide->IsClosed()) {
// creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta )
PtrOwner<ISurfTriMesh> pSci( pSfrSect->GetAuxSurf()->Clone()) ;
if ( IsNull( pSci) || ! pSci->IsValid())
return nullptr ;
pStmSwept->DoSewing( *pSci) ;
// recupero i loops alla fine
POLYLINEVECTOR vPL ;
if ( ! pStmSwept->GetLoops( vPL))
return nullptr ;
// creo la superficie alla fine e la attacco
PtrOwner<ISurfTriMesh> pSce( CreateSurfTriMesh()) ;
if ( ! pSce->CreateByRegion( vPL))
return nullptr ;
// attacco la superficie finale alla swept
pSce->Invert() ;
pStmSwept->DoSewing( *pSce) ;
}
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
double dVol ;
if ( pStmSwept->GetVolume( dVol) && dVol < 0)
pStmSwept->Invert() ;
return Release( pStmSwept) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshTransSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, double dLinTol)
{
// verifica parametri
if ( pSect == nullptr || pGuide == nullptr)
return nullptr ;
// determino se la sezione è chiusa
bool bSectClosed = pSect->IsClosed() ;
// punto iniziale della sezione e vettore a inizio guida
Point3d ptStart ;
if ( ! pSect->GetStartPoint( ptStart))
return nullptr ;
Point3d ptGuide ;
if ( ! pGuide->GetStartPoint( ptGuide))
return nullptr ;
Vector3d vtDelta = ptStart - ptGuide ;
// calcolo la polilinea che approssima la guida
PolyLine PLG ;
if ( ! pGuide->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PLG))
return nullptr ;
// determino se la guida è chiusa
bool bGuideClosed = PLG.IsClosed() ;
// calcolo la superficie
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSTM))
@@ -688,19 +1106,16 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
// superficie swept
PtrOwner<ICurve> pPrevCrv ;
Point3d ptP ;
bool bPoint = PL.GetFirstPoint( ptP) ;
bool bPoint = PLG.GetFirstPoint( ptP) ;
while ( bPoint) {
// nuova curva
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pGuide, ptP.x, ICurve::OFF_FILLET) || OffsCrv.GetCurveCount() == 0)
return nullptr ;
PtrOwner<ICurve> pCurrCrv( OffsCrv.GetLongerCurve()) ;
PtrOwner<ICurve> pCurrCrv( pSect->Clone()) ;
if ( IsNull( pCurrCrv))
return nullptr ;
pCurrCrv->Translate( ptP.y * frStart.VersY()) ;
pCurrCrv->Translate( ptP - ptStart + vtDelta) ;
// se esiste la curva precedente, costruisco la rigata (di tipo minima distanza)
if ( ! IsNull( pPrevCrv)) {
PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_ISOPAR, dLinTol)) ;
if ( IsNull( pSr))
return nullptr ;
pSTM->DoSewing( *pSr) ;
@@ -708,39 +1123,33 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
// salvo la curva come prossima precedente
pPrevCrv.Set( pCurrCrv) ;
// prossimo punto
bPoint = PL.GetNextPoint( ptP) ;
bPoint = PLG.GetNextPoint( ptP) ;
}
// se richiesti caps e sezione chiusa e guida aperta
if ( bCapEnds && bSectClosed && ! bGuideClosed) {
// verifico che le due estremità siano chiuse e piatte
POLYLINEVECTOR vPL ;
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
// calcolo la polilinea che approssima la sezione
PolyLine PLS ;
if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PLS))
return nullptr ;
Plane3d plEnds ; double dArea ;
if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
return nullptr ;
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
return nullptr ;
// aggiungo il cap sull'inizio
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
return nullptr ;
pSci->ToGlob( frStart) ;
pSTM->DoSewing( *pSci) ;
// riferimento alla fine della linea guida
Frame3d frEnd ;
Point3d ptEnd ;
pGuide->GetEndPoint( ptEnd) ;
Vector3d vtEnd ;
pGuide->GetEndDir( vtEnd) ;
frEnd.Set( ptEnd, -vtEnd, vtEnd ^ vtNorm) ;
// aggiungo il cap sulla fine
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
return nullptr ;
pSce->Invert() ;
pSce->ToGlob( frEnd) ;
pSTM->DoSewing( *pSce) ;
// verifico che la sezione sia chiusa e piatta
Plane3d plSect ; double dArea ;
if ( PLS.IsClosedAndFlat( plSect, dArea, 100 * EPS_SMALL)) {
// aggiungo il cap sull'inizio
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PLS))
return nullptr ;
pSci->Invert() ;
Point3d ptGi ; PLG.GetFirstPoint( ptGi) ;
pSci->Translate( ptGi - ptStart + vtDelta) ;
pSTM->DoSewing( *pSci) ;
// aggiungo il cap sulla fine
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PLS))
return nullptr ;
Point3d ptGe ; PLG.GetLastPoint( ptGe) ;
pSce->Translate( ptGe - ptStart + vtDelta) ;
pSTM->DoSewing( *pSce) ;
}
}
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
double dVol ;
@@ -852,7 +1261,7 @@ CalcRegionPolyLines( const CICURVEPVECTOR& vpCurve, double dLinTol,
vCrvCompo[i]->ToLoc( frRef) ;
}
// creo una matrice di interi ; ogni riga corrisponde ad un chunk, dove in posizione 0 c'è il loop esterno e nelle
// creo una matrice di interi ; ogni riga corrisponde ad un chunk, dove in posizione 0 c'è il loop esterno e nelle
// successive i loop interni
INTMATRIX vnPLIndMat ;
@@ -885,10 +1294,10 @@ CalcRegionPolyLines( const CICURVEPVECTOR& vpCurve, double dLinTol,
}
bFirstCrv = false ;
}
// ... altrimenti verifico se il loop è interno o no
// ... altrimenti verifico se il loop è interno o no
else {
// il loop è interno se è sia interno al loop esterno della riga di vnPLIndMat e allo stesso tempo
// esterno a tutti i loop già inseriti nella riga attuale.
// il loop è interno se è sia interno al loop esterno della riga di vnPLIndMat e allo stesso tempo
// esterno a tutti i loop già inseriti nella riga attuale.
// verifica rispetto loop esterno
IntersCurveCurve ccInt( *vCrvCompo[vnPLIndMat.back().front()], *vCrvCompo[j]) ;
CRVCVECTOR ccClass ;
+24 -46
View File
@@ -16,6 +16,7 @@
#include "GeoConst.h"
#include "CurveComposite.h"
#include "SurfFlatRegion.h"
#include "AdjustLoops.h"
#include "Voronoi.h"
#include "/EgtDev/Include/EGkOffsetCurve.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
@@ -36,7 +37,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
if ( nChunk == 0)
return nullptr ;
// se offset nullo, la nuova regione è la copia di quella attuale
// se offset nullo, la nuova regione è la copia di quella attuale
if ( abs( dDist) < 10 * EPS_SMALL)
return this->Clone() ;
@@ -70,7 +71,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
while ( bOk && ! IsNull( pOffs)) {
if ( pOffs->GetType() == CRV_COMPO) {
CurveComposite* pOffsCompo = GetBasicCurveComposite( pOffs) ;
// assegno proprietà
// assegno proprietà
pOffsCompo->SetTempProp( j, 1) ;
for ( int k = 0 ; k < pOffsCompo->GetCurveCount() ; ++k)
pOffsCompo->SetCurveTempProp( k, j, 1) ;
@@ -80,7 +81,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
}
else
pOffs->SetTempProp( j, 1) ;
// se prima curva esterna, è il primo contorno esterno della nuova regione
// se prima curva esterna, è il primo contorno esterno della nuova regione
if ( j == 0 && bFirstCurve) {
if ( ! pSfrChk->AddExtLoop( Release( pOffs)))
return nullptr ;
@@ -137,7 +138,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
// -------------------- OFFSET CON VORONOI -------------------------------------
else {
// verifico se oggetto Voronoi della superficie è definito
// verifico se oggetto Voronoi della superficie è definito
if ( m_pVoronoiObj == nullptr)
CalcVoronoiObject() ;
@@ -146,51 +147,28 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
if ( ! m_pVoronoiObj->CalcOffset( vOffs, dDist, nType))
return nullptr ;
// costruisco la superficie
if ( vOffs.size() > 0) {
BOOLVECTOR vbAddOrSub( vOffs.size(), true) ;
int nFirstId = -1 ;
for ( int i = 0 ; i < ( int)vOffs.size() ; i ++) {
// porto nel frame della flat region
PCRV_DEQUE vLoops ;
for ( int i = 0 ; i < int( vOffs.size()) ; i ++) {
vOffs[i]->ToLoc( m_frF) ;
// calcolo orientamento della curva
double dAreaXY ;
if ( ! vOffs[i]->GetAreaXY( dAreaXY))
return nullptr ;
vbAddOrSub[i] = ( dAreaXY > SQ_EPS_SMALL) ;
// verifico se è il primo loop esterno
if ( nFirstId == -1 && vbAddOrSub[i])
nFirstId = i ;
}
// inizializzo la superficie
if ( nFirstId != -1 && ! pSfr->AddExtLoop( Release( vOffs[nFirstId])))
return nullptr ;
if ( pSfr->IsValid()) {
for ( int i = 0 ; i < ( int)vOffs.size() ; i ++) {
// verifico non sia il primo loop esterno
if ( i == nFirstId)
continue ;
// costruisco la superficie associata
PtrOwner<SurfFlatRegion> pSrfCrv( CreateBasicSurfFlatRegion()) ;
if ( IsNull( pSrfCrv) || ! pSrfCrv->AddExtLoop( Release( vOffs[i])))
return nullptr ;
if ( ! pSrfCrv->IsValid())
continue ;
// aggiungo o sottraggo
if ( vbAddOrSub[i]) {
if ( ! pSfr->Add( *pSrfCrv))
return nullptr ;
}
else {
pSrfCrv->Invert() ;
if ( ! pSfr->Subtract( *pSrfCrv))
return nullptr ;
}
// rimuovo eventuali sovrapposizioni
ICURVEPLIST CrvLst ;
AdjustLoops( Release( vOffs[i]), CrvLst, true) ;
for ( auto pCrv : CrvLst) {
pCrv->SetExtrusion( Z_AX) ;
vLoops.emplace_back( pCrv) ;
}
}
// verifico di avere ancora dei loops
if ( vLoops.size() > 0) {
pSfr.Set( MyNewSurfFromLoops( vLoops)) ;
if ( IsNull( pSfr)) {
MyTestAndDelete( vLoops) ;
return nullptr ;
}
}
}
}
@@ -207,7 +185,7 @@ SurfFlatRegion::Offset( double dDist, int nType)
if ( nChunk == 0)
return false ;
// se offset nullo, non devo fare alcunchè
// se offset nullo, non devo fare alcunchè
if ( abs( dDist) < 10 * EPS_SMALL)
return true ;
-4
View File
@@ -35,7 +35,6 @@
#include "/EgtDev/Include/EGkPolygon3d.h"
#include "/EgtDev/Include/EgtPerfCounter.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EGkGeoObjSave.h"
#include <algorithm>
using namespace std ;
@@ -1486,9 +1485,6 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
if ( bModif)
bContinue = ( AdjustVertices() && DoCompacting() && SurfB.AdjustVertices() && SurfB.DoCompacting()) ;
SaveGeoObj( this, "C:\\Users\\riccardo.elitropi\\Desktop\\SurfA.nge") ;
SaveGeoObj( SurfB.Clone(), "C:\\Users\\riccardo.elitropi\\Desktop\\SurfB.nge") ;
// Triangoli sovrapposti
if ( bContinue) {
int nTriaNum2A = GetTriangleSize() ;
+6 -3
View File
@@ -17,12 +17,15 @@
#include "GeoObjRW.h"
#include "Tool.h"
#include "/EgtDev/Include/EGkVolZmap.h"
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
#include "/EgtDev/Include/EGkIntersLineVolZmap.h"
#include <unordered_map>
#include <stack>
#include <mutex>
#include <atomic>
// ------------------------- FORWARD -------------------------------------------------------------
class IntersParLinesSurfTm ;
// ------------------------- STRUTTURE -----------------------------------------------------------
struct AppliedVector {
Point3d ptPApp ;
@@ -112,8 +115,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW
const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs,
const Point3d& ptPe, const Vector3d& vtDe, const Vector3d& vtAe) override ;
bool GetDepth( const Point3d& ptP, const Vector3d& vtD, double& dInLength, double& dOutLength, bool bExact) const override ;
bool GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTOR& vIntersInfo) const override ;
bool GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) const override ;
bool CDeBox( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, bool bPrecise = false) const override ;
bool CDeSphere( const Point3d& ptCenter, double dRad, double dSafeDist, bool bPrecise = false) const override ;
bool CDeCylinder( const Frame3d& frCyl, double dR, double dH, double dSafeDist, bool bPrecise = false) const override ;
@@ -149,6 +150,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
{ if ( ! CopyFrom( stSrc))
LOG_ERROR( GetEGkLogger(), "VolZmap : copy error")
return *this ; }
bool GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTOR& vIntersInfo) const ;
bool GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) const ;
private :
enum CubeType { VOX_EXTERN = 1,
+16 -8
View File
@@ -2912,8 +2912,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
int nNumVox ;
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
double dCosDN = vtDir * trTria.GetN() ;
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
nNumVox, nB, ptLineTria1, trTria) ;
nNumVox, nB, trTria, dCosDN, ptLineTria1) ;
}
// altrimenti ci sono due intersezioni
else {
@@ -2921,8 +2922,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
double dCosDN = vtDir * trTria.GetN() ;
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
nNumVox, nB, ptLineTria1, ptLineTria2, trTria) ;
nNumVox, nB, trTria, dCosDN, ptLineTria1, ptLineTria2) ;
}
}
}
@@ -2948,8 +2950,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
int nNumVox ;
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
double dCosDN = vtDir * trTria.GetN() ;
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
nNumVox, nB, ptLineTria1, trTria) ;
nNumVox, nB, trTria, dCosDN, ptLineTria1) ;
}
// altrimenti ci sono due intersezioni
else {
@@ -2957,8 +2960,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
double dCosDN = vtDir * trTria.GetN() ;
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
nNumVox, nB, ptLineTria1, ptLineTria2, trTria) ;
nNumVox, nB, trTria, dCosDN, ptLineTria1, ptLineTria2) ;
}
}
}
@@ -2974,15 +2978,17 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
continue ;
// se altrimenti c'è una sola intersezione
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
double dCosDN = vtDir * trTria.GetN() ;
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
-1, nB, ptLineTria1, trTria) ;
-1, nB, trTria, dCosDN, ptLineTria1) ;
}
// altrimenti ci sono due intersezioni
else {
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
double dCosDN = vtDir * trTria.GetN() ;
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
-1, nB, ptLineTria1, ptLineTria2, trTria) ;
-1, nB, trTria, dCosDN, ptLineTria1, ptLineTria2) ;
}
}
}
@@ -3007,8 +3013,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
else if ( nIntType == ILTT_VERT || nIntType == ILTT_EDGE || nIntType == ILTT_IN) {
int nNumVox ;
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
double dCosDN = vtDir * trTria.GetN() ;
vIntersInfo.emplace_back( nIntType, ( ptLineTria1 - ptP) * vtDir,
nNumVox, nB, ptLineTria1, trTria) ;
nNumVox, nB, trTria, dCosDN, ptLineTria1) ;
}
// altrimenti ci sono due intersezioni
else {
@@ -3016,8 +3023,9 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
GetVoxNFromIJK( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], nNumVox) ;
double dP1 = ( ptLineTria1 - ptP) * vtDir ;
double dP2 = ( ptLineTria2 - ptP) * vtDir ;
double dCosDN = vtDir * trTria.GetN() ;
vIntersInfo.emplace_back( nIntType, ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1),
nNumVox, nB, ptLineTria1, ptLineTria2, trTria) ;
nNumVox, nB, trTria, dCosDN, ptLineTria1, ptLineTria2) ;
}
}
}
+1
View File
@@ -17,6 +17,7 @@
#include "CurveLine.h"
#include "VolZmap.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include <future>
+49 -23
View File
@@ -79,7 +79,7 @@ Voronoi::AddCurve( const ICurve* pCrv)
if ( pCrv == nullptr)
return false ;
// verifico se è una linea
// verifico se è una linea
int nType = pCrv->GetType() ;
bool bIsLine = ( nType == CRV_LINE) ;
if ( nType == CRV_COMPO) {
@@ -92,7 +92,7 @@ Voronoi::AddCurve( const ICurve* pCrv)
// verifico sia piana e trovo piano su cui giace
Plane3d plPlane ;
if ( bIsLine) {
// linea è sicuramente piana. Scelgo piano definito dall'estrusione ( se definita)
// linea è sicuramente piana. Scelgo piano definito dall'estrusione ( se definita)
Point3d ptS ; pCrv->GetStartPoint( ptS) ;
Vector3d vtExtr ; pCrv->GetExtrusion( vtExtr) ;
if ( ! vtExtr.IsSmall())
@@ -110,7 +110,7 @@ Voronoi::AddCurve( const ICurve* pCrv)
m_Frame.Set( plPlane.GetPoint(), plPlane.GetVersN()) ;
}
else {
// altrimenti verifico sia complanare ad eventuali curve già presenti
// altrimenti verifico sia complanare ad eventuali curve già presenti
if ( ! AreSameOrOppositeVectorApprox( m_Frame.VersZ(), plPlane.GetVersN()) || ! PointInPlaneApprox( m_Frame.Orig(), plPlane))
return false ;
}
@@ -122,7 +122,7 @@ Voronoi::AddCurve( const ICurve* pCrv)
pCrvLoc->ToLoc( m_Frame) ;
try {
// verifico se oggetto vroni è stato inizializzato
// verifico se oggetto vroni è stato inizializzato
if ( m_vroni == nullptr) {
m_vroni = new( nothrow) vroniObject() ;
if ( m_vroni == nullptr)
@@ -165,7 +165,7 @@ Voronoi::AddSurfFlatRegion( const ISurfFlatRegion* pSfr)
m_Frame.Set( ptCen, vtN) ;
}
else {
// verifico sia complanare ad eventuali curve già presenti
// verifico sia complanare ad eventuali curve già presenti
Plane3d plPlane ;
plPlane.Set( ptCen, pSfr->GetNormVersor()) ;
if ( ! AreSameOrOppositeVectorApprox( m_Frame.VersZ(), pSfr->GetNormVersor()) || ! PointInPlaneApprox( m_Frame.Orig(), plPlane))
@@ -173,7 +173,7 @@ Voronoi::AddSurfFlatRegion( const ISurfFlatRegion* pSfr)
}
try {
// verifico se oggetto vroni è stato inizializzato
// verifico se oggetto vroni è stato inizializzato
if ( m_vroni == nullptr) {
m_vroni = new( nothrow) vroniObject() ;
if ( m_vroni == nullptr)
@@ -315,7 +315,7 @@ Voronoi::AddCompoToVroni( const ICurveComposite* pCompo, int& nVroniCrv, int nLo
for ( int i = 0 ; i < pCopy->GetCurveCount() ; i++) {
Point3d ptForcedEnd = P_INVALID ;
// se curva è chiusa, forzo l'end point a coincidere con lo start ( per le tolleranze di vroni)
// se curva è chiusa, forzo l'end point a coincidere con lo start ( per le tolleranze di vroni)
if ( i == pCopy->GetCurveCount() - 1 && bClosed)
pCompo->GetStartPoint( ptForcedEnd) ;
@@ -359,7 +359,7 @@ Voronoi::AddBezierToVroni( const ICurveBezier* pBezier, int& nVroniCrv, int nLoo
ICurve*
Voronoi::GetCurve( int nId) const
{
// verifico validità indice
// verifico validità indice
if ( nId < 0 || nId > ( int)m_vpCrvs.size() - 1)
return nullptr ;
// ne faccio una copia
@@ -375,11 +375,11 @@ Voronoi::GetCurve( int nId) const
bool
Voronoi::CalcVoronoi( int nBound)
{
// se già stato calcolato con lo stesso bound non devo fare nulla
// se già stato calcolato con lo stesso bound non devo fare nulla
if ( m_bVDComputed && nBound == m_nBound)
return true ;
// se già stato calcolato reset dei dati
// se già stato calcolato reset dei dati
if ( m_bVDComputed)
m_vroni->ResetVoronoiDiagram() ;
@@ -389,8 +389,8 @@ Voronoi::CalcVoronoi( int nBound)
// calcolo
m_bVDComputed = true ;
string sTmp = "" ;
m_vroni->apiComputeVD( false, true, false, m_nBound, 0, 0, &sTmp[0], false, false, false, &sTmp[0], true) ;
m_vroni->apiComputeVD( false, true, false, m_nBound, 0, 0, &sTmp[0], false, false, false, &sTmp[0], true) ;
return true ;
}
@@ -501,6 +501,9 @@ Voronoi::CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound)
if ( ! IsNull( pCrv) && pCrv->IsValid())
vCrvs.emplace_back( Release( pCrv)) ;
}
// libero la memoria di vroni utilizzata per calcolare bisettore
m_vroni->apiFreeBisectorBuffer() ;
}
catch (...) {
LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ;
@@ -542,6 +545,9 @@ Voronoi::CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide)
vCrvs.emplace_back( Release( pCrv)) ;
}
}
// libero la memoria di vroni utilizzata per calcolare bisettore
m_vroni->apiFreeBisectorBuffer() ;
}
catch (...) {
LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ;
@@ -651,12 +657,12 @@ Voronoi::CalcFatCurve( ICURVEPOVECTOR& vCrvs, double dOffs, bool bSquareEnds, bo
// sistemo i raccordi
if ( bClosed && bSquareMids) {
// se curva è chiusa tutti i raccordi rispondono a bSquareMids
// se curva è chiusa tutti i raccordi rispondono a bSquareMids
IdentifyFillets( pCrvOffs, dOffs) ;
AdjustCurveFillets( pCrvOffs, dOffs, ICurve::OFF_EXTEND) ;
}
else if ( ! bClosed && ( bSquareMids || bSquareEnds)) {
// se curva è aperta devo distinguere i raccordi interni da quelli relativi agli estremi e
// se curva è aperta devo distinguere i raccordi interni da quelli relativi agli estremi e
// modificare solo quelli richiesti
for ( int j = 0 ; j < pCrvOffs->GetCurveCount() ; j ++) {
int nOrigCrv ; pCrvOffs->GetCurveTempProp( j, nOrigCrv) ;
@@ -738,13 +744,13 @@ Voronoi::CalcVroniOffset( ICRVCOMPOPLIST& OffsList, double dOffs, bool bRightOff
bOk = pCrvOffs->AddCurve( Release( pArc)) ;
}
// se la curva è stata aggiunta
// se la curva è stata aggiunta
if ( bOk) {
// setto come info la sottocurva da cui si è generata
// setto come info la sottocurva da cui si è generata
int nCurrCrvId = pCrvOffs->GetCurveCount() - 1 ;
pCrvOffs->SetCurveTempProp( nCurrCrvId, nOrigCrv + 1, 0) ;
pCrvOffs->SetCurveTempProp( nCurrCrvId, nOrigLoop, 1) ;
// verifico se è raccordo relativo agli estremi della curva
// verifico se è raccordo relativo agli estremi della curva
if ( nOrigCrv == -1 && ( nOrigPnt == 0 || nOrigPnt == nOrigCrvCnt))
pCrvOffs->SetCurveTempParam( nCurrCrvId, 1.0, 0) ;
}
@@ -757,6 +763,9 @@ Voronoi::CalcVroniOffset( ICRVCOMPOPLIST& OffsList, double dOffs, bool bRightOff
if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid())
OffsList.push_back( Release( pCrvOffs)) ;
}
// libero la memoria di vroni dedicata agli offset
m_vroni->apiFreeOffsetData() ;
}
catch (...) {
LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ;
@@ -789,7 +798,7 @@ Voronoi::VerifyCurvesValidityForOffset()
if ( m_vpCrvs.size() == 1)
return true ;
// se ho più curve, devono essere tutte chiuse
// se ho più curve, devono essere tutte chiuse
for ( auto pCrv : m_vpCrvs) {
if ( ! pCrv->IsClosed())
return false ;
@@ -809,12 +818,29 @@ Voronoi::VerifyCurvesValidityForOffset()
// se curva con orientamento principale verifico sia esterna a tutte le altre curve con orientamento principale
if ( vArea[i] * dRefArea > EPS_SMALL) {
for ( int j = i + 1 ; j < ( int)vArea.size() ; j++) {
if ( vArea[i] * vArea[j] > EPS_SMALL) {
for ( int j = 0 ; j < ( int)vArea.size() ; j++) {
if ( j != i && vArea[i] * vArea[j] > EPS_SMALL) {
IntersCurveCurve ccInt( *m_vpCrvs[i], *m_vpCrvs[j]) ;
int nRes = ccInt.GetRegionCurveClassification() ;
if ( ( bRefCCW && nRes != CCREGC_OUT) || ( ! bRefCCW && nRes != CCREGC_IN1))
if ( nRes == CCREGC_NULL || nRes == CCREGC_SAME || nRes == CCREGC_INTERS)
return false ;
if ( ( bRefCCW && nRes == CCREGC_IN1) || ( ! bRefCCW && nRes == CCREGC_IN2)) {
// se è interna ad una curva con orientamento principale, verifico sia esterna ad almeno una curva con orientamento
// diverso dal principale
bool bFound = false ;
for ( int k = 0 ; k < ( int)vArea.size() ; k++) {
if ( k != i && vArea[i] * vArea[k] < EPS_SMALL) {
IntersCurveCurve ccInt( *m_vpCrvs[i], *m_vpCrvs[k]) ;
int nRes = ccInt.GetRegionCurveClassification() ;
if ( ( bRefCCW && nRes == CCREGC_OUT) || ( ! bRefCCW && nRes == CCREGC_IN1)) {
bFound = true ;
break ;
}
}
}
if ( ! bFound)
return false ;
}
}
}
}
@@ -884,7 +910,7 @@ Voronoi::AdjustOpenOffsetCurve( ICurveComposite& pCompo, double dOffs)
// mi posiziono dopo la junction
pCompo.ChangeStartPoint( vJunctions[0] + 1) ;
delete( pCompo.RemoveFirstOrLastCurve()) ;
// verifico validità della curva
// verifico validità della curva
int nSide = GetOffsetCurveSide( pCompo, 0) ;
if ( nSide == nSideRef) {
// scorro fino alla prima curva non valida ed elimino la curva da quel punto fino alla fine
@@ -895,7 +921,7 @@ Voronoi::AdjustOpenOffsetCurve( ICurveComposite& pCompo, double dOffs)
}
}
else {
// elimino finchè non trovo una curva valida
// elimino finchè non trovo una curva valida
while( nSide != nSideRef && pCompo.IsValid()) {
delete( pCompo.RemoveFirstOrLastCurve( false)) ;
if ( pCompo.IsValid())