Merge commit '8710115634c9be74c0a8ead37b0bb32144f84b96' into TempForVmill
This commit is contained in:
Binary file not shown.
@@ -151,6 +151,7 @@ copy $(TargetPath) \EgtProg\DllD32</Command>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -243,6 +244,7 @@ copy $(TargetPath) \EgtProg\Dll32</Command>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -588,6 +590,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="IntersArcArc.h" />
|
||||
<ClInclude Include="IntersCrvCompoCrvCompo.h" />
|
||||
<ClInclude Include="IntersLineArc.h" />
|
||||
<ClInclude Include="IntersLineBox.h" />
|
||||
<ClInclude Include="IntersLineLine.h" />
|
||||
<ClInclude Include="IntersLineSurfStd.h" />
|
||||
<ClInclude Include="IntersLineTria.h" />
|
||||
|
||||
@@ -1085,6 +1085,9 @@
|
||||
<ClInclude Include="earcut.hpp">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntersLineBox.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
@@ -684,7 +684,6 @@ HashGrids3d::Update( void)
|
||||
double dSize = 0 ;
|
||||
Obj.box.GetDiameter( dSize) ;
|
||||
double dCellSpan = pGrid->GetCellSpan() ;
|
||||
|
||||
if ( dSize >= dCellSpan || dSize < ( dCellSpan / hierarchyFactor)) {
|
||||
pGrid->Remove( Obj) ;
|
||||
addGrid( Obj) ;
|
||||
|
||||
+127
-108
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
// EgalTech 2020-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineBox.cpp Data : 07.05.20 Versione : 2.2e1
|
||||
// File : IntersLineBox.cpp Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Implementazione della intersezione linea/box.
|
||||
//
|
||||
//
|
||||
@@ -13,13 +13,77 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
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.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptMin, const Point3d& ptMax,
|
||||
double& dU1, double& dU2)
|
||||
{
|
||||
// Verifico il versore
|
||||
if ( vtL.IsSmall())
|
||||
return false ;
|
||||
|
||||
// Verifico gli estremi del box
|
||||
if ( ptMin.x > ptMax.x + EPS_SMALL ||
|
||||
ptMin.y > ptMax.y + EPS_SMALL ||
|
||||
ptMin.z > ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// Casi di intersezione impossibile
|
||||
if ( abs( vtL.x) < EPS_ZERO && ( ptL.x < ptMin.x - EPS_SMALL || ptL.x > ptMax.x + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtL.y) < EPS_ZERO && ( ptL.y < ptMin.y - EPS_SMALL || ptL.y > ptMax.y + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtL.z) < EPS_ZERO && ( ptL.z < ptMin.z - EPS_SMALL || ptL.z > ptMax.z + EPS_SMALL))
|
||||
return false ;
|
||||
|
||||
// Parametri degli estremi della retta
|
||||
dU1 = -INFINITO ;
|
||||
dU2 = INFINITO ;
|
||||
|
||||
// Confronto con piani YZ (perpendicolari ad asse X)
|
||||
if ( vtL.x > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.x - ptL.x) / vtL.x) ;
|
||||
dU2 = min( dU2, ( ptMax.x - ptL.x) / vtL.x) ;
|
||||
}
|
||||
else if ( vtL.x < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.x - ptL.x) / vtL.x) ;
|
||||
dU2 = min( dU2, ( ptMin.x - ptL.x) / vtL.x) ;
|
||||
}
|
||||
|
||||
// Confronto con piani ZX (perpendicolari ad asse Y)
|
||||
if ( vtL.y > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.y - ptL.y) / vtL.y) ;
|
||||
dU2 = min( dU2, ( ptMax.y - ptL.y) / vtL.y) ;
|
||||
}
|
||||
else if ( vtL.y < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.y - ptL.y) / vtL.y) ;
|
||||
dU2 = min( dU2, ( ptMin.y - ptL.y) / vtL.y) ;
|
||||
}
|
||||
|
||||
// Confronto con piani XY (perpendicolari ad asse Z)
|
||||
if ( vtL.z > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.z - ptL.z) / vtL.z) ;
|
||||
dU2 = min( dU2, ( ptMax.z - ptL.z) / vtL.z) ;
|
||||
}
|
||||
else if ( vtL.z < -EPS_ZERO){
|
||||
dU1 = max( dU1, ( ptMax.z - ptL.z) / vtL.z) ;
|
||||
dU2 = min( dU2, ( ptMin.z - ptL.z) / vtL.z) ;
|
||||
}
|
||||
|
||||
return ( dU2 >= dU1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL1, const Point3d& ptL2, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite)
|
||||
@@ -38,114 +102,69 @@ bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite)
|
||||
{
|
||||
// Recupero i dati del Box
|
||||
Point3d ptMin ;
|
||||
double dDimX, dDimY, dDimZ ;
|
||||
if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimZ))
|
||||
Point3d ptMin, ptMax ;
|
||||
if ( ! b3Box.GetMinMax( ptMin, ptMax))
|
||||
return false ;
|
||||
// Contorno di base
|
||||
PolyLine PL ;
|
||||
PL.AddUPoint( 0, ptMin) ;
|
||||
PL.AddUPoint( 1, ptMin + Vector3d( dDimX, 0, 0)) ;
|
||||
PL.AddUPoint( 2, ptMin + Vector3d( dDimX, dDimY, 0)) ;
|
||||
PL.AddUPoint( 3, ptMin + Vector3d( 0, dDimY, 0)) ;
|
||||
PL.Close() ;
|
||||
// Vettore altezza
|
||||
Vector3d vtExtr( 0, 0, dDimZ) ;
|
||||
// Creo la superficie trimesh equivalente
|
||||
SurfTriMesh Stm ;
|
||||
if ( ! Stm.CreateByExtrusion( PL, vtExtr))
|
||||
return false ;
|
||||
SurfTriMesh StmBot ;
|
||||
if ( ! StmBot.CreateByFlatContour( PL))
|
||||
return false ;
|
||||
StmBot.Invert() ;
|
||||
SurfTriMesh StmTop ;
|
||||
if ( ! StmTop.CreateByFlatContour( PL))
|
||||
return false ;
|
||||
StmTop.Translate( vtExtr) ;
|
||||
if ( ! Stm.DoSewing( StmBot) || ! Stm.DoSewing( StmTop))
|
||||
return false ;
|
||||
// Calcolo l'intersezione
|
||||
ILSIVECTOR vInfo ;
|
||||
if ( ! IntersLineSurfTm( ptL, vtL, dLen, Stm, vInfo, bFinite))
|
||||
return false ;
|
||||
// ciclo sulle intersezioni
|
||||
double dUcurr = -INFINITO ;
|
||||
for ( const auto& Info : vInfo) {
|
||||
// se intersezione puntuale
|
||||
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||
int nFlag = ILBT_TOUCH ;
|
||||
if ( Info.dCosDN > EPS_ZERO)
|
||||
nFlag = ILBT_OUT ;
|
||||
else if ( Info.dCosDN < -EPS_ZERO)
|
||||
nFlag = ILBT_IN ;
|
||||
vInters.emplace_back( nFlag, Info.dU) ;
|
||||
dUcurr = Info.dU ;
|
||||
|
||||
// Pulisco vettore intersezioni
|
||||
vInters.clear() ;
|
||||
|
||||
// Eseguo intersezione della linea completa
|
||||
double dU1, dU2 ;
|
||||
bool bInters = IntersLineBox( ptL, vtL, b3Box.GetMin(), b3Box.GetMax(), dU1, dU2) ;
|
||||
|
||||
// Se non c'è intersezione
|
||||
if ( ! bInters || ( bFinite && ( dU1 > dLen + EPS_SMALL || dU2 < -EPS_SMALL)))
|
||||
return true ;
|
||||
|
||||
// Se le due intersezioni coincidono
|
||||
if ( ( dU2 - dU1) < EPS_SMALL) {
|
||||
double dU = ( dU1 + dU2) / 2 ;
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_TOUCH, dU) ;
|
||||
}
|
||||
// se altrimenti intersezione con coincidenza
|
||||
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
||||
if ( Info.dU > dUcurr - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_TG_INI, Info.dU) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, Info.dU2) ;
|
||||
dUcurr = Info.dU2 ;
|
||||
else {
|
||||
if ( dU > - EPS_SMALL && dU < dLen + EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_TOUCH, Clamp( dU, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
// elimino intersezioni ripetute
|
||||
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||
// intersezione precedente
|
||||
size_t i = j - 1 ;
|
||||
// se sono dello stesso tipo, elimino una delle due
|
||||
if ( vInters[i].first == vInters[j].first) {
|
||||
// se entranti elimino la prima
|
||||
if ( vInters[i].first == ILBT_IN || vInters[i].first == ILBT_TG_INI)
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
// altrimenti la seconda
|
||||
else
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se hanno lo stesso parametro
|
||||
else if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
||||
// se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
|
||||
if ( ( vInters[i].first == ILBT_IN && vInters[j].first == ILBT_OUT) ||
|
||||
( vInters[i].first == ILBT_OUT && vInters[j].first == ILBT_IN)) {
|
||||
vInters[i].first = ILBT_TOUCH ;
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se prima puntuale e l'altra inizio o fine di coincidenza, elimino la prima
|
||||
else if ( ( vInters[i].first == ILBT_IN || vInters[i].first == ILBT_OUT || vInters[i].first == ILBT_TOUCH) &&
|
||||
( vInters[j].first == ILBT_TG_INI || vInters[j].first == ILBT_TG_FIN)) {
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se prima inizio o fine di coincidenza e l'altra puntuale, elimino la seconda
|
||||
else if ( ( vInters[i].first == ILBT_TG_INI || vInters[i].first == ILBT_TG_FIN) &&
|
||||
( vInters[j].first == ILBT_IN || vInters[j].first == ILBT_OUT || vInters[j].first == ILBT_TOUCH)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
|
||||
else if ( ( vInters[i].first == ILBT_TG_FIN && vInters[j].first == ILBT_TG_INI) ||
|
||||
( vInters[i].first == ILBT_TG_INI && vInters[j].first == ILBT_TG_FIN)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
// passo alla successiva
|
||||
++ j ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Se sono due intersezioni con la linea giacente su una faccia del box
|
||||
if ( ( abs( vtL.x) < EPS_ZERO && ( abs( ptL.x - ptMin.x) < EPS_SMALL || abs( ptL.x - ptMax.x) < EPS_SMALL)) ||
|
||||
( abs( vtL.y) < EPS_ZERO && ( abs( ptL.y - ptMin.y) < EPS_SMALL || abs( ptL.y - ptMax.y) < EPS_SMALL)) ||
|
||||
( abs( vtL.z) < EPS_ZERO && ( abs( ptL.z - ptMin.z) < EPS_SMALL || abs( ptL.z - ptMax.z) < EPS_SMALL))) {
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_TG_INI, dU1) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, dU2) ;
|
||||
}
|
||||
else {
|
||||
if ( dU1 > dLen - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_IN, dLen) ;
|
||||
else if ( dU2 < EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||
else {
|
||||
vInters.emplace_back( ILBT_TG_INI, Clamp( dU1, 0., dLen)) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, Clamp( dU2, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Altrimenti sono due intersezioni con attraversamento
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_IN, dU1) ;
|
||||
vInters.emplace_back( ILBT_OUT, dU2) ;
|
||||
}
|
||||
else {
|
||||
if ( dU1 > dLen - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_IN, dLen) ;
|
||||
else if ( dU2 < EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||
else {
|
||||
vInters.emplace_back( ILBT_IN, Clamp( dU1, 0., dLen)) ;
|
||||
vInters.emplace_back( ILBT_OUT, Clamp( dU2, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2022-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineBox.h Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Dichiarazione delle funzioni base per intersezione linea/box.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 08.01.22 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e box allineato agli assi sono nel medesimo riferimento.
|
||||
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptMin, const Point3d& ptMax,
|
||||
double& dU1, double& dU2) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
TestIntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptMin, const Point3d& ptMax)
|
||||
{
|
||||
double dU1, dU2 ;
|
||||
return IntersLineBox( ptL, vtL, ptMin, ptMax, dU1, dU2) ;
|
||||
}
|
||||
+3
-56
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2017-2018
|
||||
// EgalTech 2017-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineSurfStd.cpp Data : 03.12.18 Versione : 1.9l1
|
||||
// File : IntersLineSurfStd.cpp Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Implementazione delle funzioni di intersezione
|
||||
// componente lineare e superficie standard.
|
||||
//
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "IntersLineSurfStd.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
@@ -21,60 +22,6 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Punti e vettore devono essere espressi nel medesimo sistema di riferimento.
|
||||
// Il box è allineato con gli assi di questo sistema di riferimento.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
|
||||
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2)
|
||||
{
|
||||
// Casi di intersezione impossibile
|
||||
if ( abs( vtV.x) < EPS_ZERO && ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtV.y) < EPS_ZERO && ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtV.z) < EPS_ZERO && ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL))
|
||||
return false ;
|
||||
|
||||
// Inizializzo parametri intersezioni
|
||||
dU1 = -INFINITO ;
|
||||
dU2 = INFINITO ;
|
||||
|
||||
// Confronto con piani YZ (perpendicolari ad asse X)
|
||||
if ( vtV.x > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ;
|
||||
dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ;
|
||||
}
|
||||
else if ( vtV.x < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ;
|
||||
dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ;
|
||||
}
|
||||
|
||||
// Confronto con piani ZX (perpendicolari ad asse Y)
|
||||
if ( vtV.y > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ;
|
||||
dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ;
|
||||
}
|
||||
else if ( vtV.y < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ;
|
||||
dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ;
|
||||
}
|
||||
|
||||
// Confronto con piani XY (perpendicolari ad asse Z)
|
||||
if ( vtV.z > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ;
|
||||
dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ;
|
||||
}
|
||||
else if ( vtV.z < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ;
|
||||
dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ;
|
||||
}
|
||||
|
||||
return ( dU2 >= dU1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
LineDisc( const Point3d& ptPLine, const Vector3d& vtVLine,
|
||||
|
||||
@@ -34,11 +34,6 @@
|
||||
// Costanti tipologia di componente lineare
|
||||
enum LinType { Line = 0, Ray = 1, Segment = 2} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
|
||||
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) ;
|
||||
|
||||
|
||||
// Costanti tipologia di intersezioni fra un componente lineare e un disco
|
||||
enum LinCompDiscIntersType { D_ERROR_INT = -1, D_NO_INTERS = 0, D_BOUNDARY_INT_LINE_NOT_IN_PLANE = 1,
|
||||
D_INNER_INT_LINE_NOT_IN_PLANE = 2, D_ONE_INT_LINE_ON_PLANE = 3,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2019
|
||||
// EgalTech 2015-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineSurfTm.cpp Data : 09.03.15 Versione : 2.1b6
|
||||
// File : IntersLineSurfTm.cpp Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Implementazione della intersezione linea/superficie trimesh.
|
||||
//
|
||||
//
|
||||
@@ -14,8 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "ProjPlane.h"
|
||||
#include "IntersLineSurfStd.h"
|
||||
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
|
||||
|
||||
+34
-6
@@ -1,8 +1,8 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineBox.cpp Data : 07.05.20 Versione : 2.2e1
|
||||
// Contenuto : Implementazione della intersezione linea/box.
|
||||
// File : IntersPlaneBox.cpp Data : 07.05.20 Versione : 2.2e1
|
||||
// Contenuto : Implementazione della intersezione piano/box.
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -20,19 +20,47 @@
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Box e piano devono essere nello stesso riferimento. Il box deve essere axis aligned.
|
||||
bool
|
||||
IntersPlaneBox( const Point3d& ptOn, const Vector3d& vtN, const BBox3d& b3Box,
|
||||
TestIntersPlaneBox( const Plane3d& plPlane, const BBox3d& b3Box)
|
||||
{
|
||||
// Verifica del piano
|
||||
if ( ! plPlane.IsValid())
|
||||
return false ;
|
||||
// Centro e estensione del box
|
||||
Point3d ptCen ;
|
||||
Vector3d vtExt ;
|
||||
if ( ! b3Box.GetCenterExtent( ptCen, vtExt))
|
||||
return false ;
|
||||
// Distanza del centro dal piano
|
||||
double dDist = DistPointPlane( ptCen, plPlane) ;
|
||||
// Proiezione dell'estensione sulla normale al piano
|
||||
Vector3d vtN = plPlane.GetVersN() ;
|
||||
double dProjExt = vtExt.x * abs( vtN.x) + vtExt.y * abs( vtN.y) + vtExt.z * abs( vtN.z) ;
|
||||
// Confronto distanza del centro con estensione proiettata
|
||||
return ( abs( dDist) < dProjExt + EPS_SMALL) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersPlaneBox( const Plane3d& plPlane, const BBox3d& b3Box,
|
||||
PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria)
|
||||
{
|
||||
// Creo il piano
|
||||
Plane3d plPlane ;
|
||||
if ( ! plPlane.Set( ptOn, vtN))
|
||||
// Verifico il piano
|
||||
if ( ! plPlane.IsValid())
|
||||
return false ;
|
||||
// Recupero i dati del Box
|
||||
Point3d ptMin ;
|
||||
double dDimX, dDimY, dDimZ ;
|
||||
if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimZ))
|
||||
return false ;
|
||||
// Pulisco vettori intersezioni
|
||||
vPnt.clear() ;
|
||||
vBpt.clear() ;
|
||||
vTria.clear() ;
|
||||
// Verifico se può esistere intersezione
|
||||
if ( ! TestIntersPlaneBox( plPlane, b3Box))
|
||||
return true ;
|
||||
// Contorno di base
|
||||
PolyLine PL ;
|
||||
PL.AddUPoint( 0, ptMin) ;
|
||||
|
||||
+5
-3
@@ -1695,8 +1695,10 @@ SurfTriMesh::TestSealing( void)
|
||||
// verifico le adiacenze
|
||||
if ( m_vTria[i].nIdAdjac[0] == SVT_NULL ||
|
||||
m_vTria[i].nIdAdjac[1] == SVT_NULL ||
|
||||
m_vTria[i].nIdAdjac[2] == SVT_NULL)
|
||||
m_vTria[i].nIdAdjac[2] == SVT_NULL) {
|
||||
bClosed = false ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// aggiorno la chiusura della superficie
|
||||
@@ -1716,7 +1718,7 @@ SurfTriMesh::AdjustTopology( void)
|
||||
return true ;
|
||||
}
|
||||
// dichiaro sfaccettatura da ricalcolare
|
||||
ResetFaceting() ;
|
||||
m_bFaceted = false ;
|
||||
// invalido calcolo connessione
|
||||
m_nParts = - 1 ;
|
||||
// verifica indici
|
||||
@@ -2982,7 +2984,7 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther, dou
|
||||
}
|
||||
int nVIdSize = int( vVId.size()) ;
|
||||
|
||||
// inserisco i triangoli dell'altra trimesh
|
||||
// aggiungo i triangoli dell'altra trimesh
|
||||
for ( int nOtId = 0 ; nOtId < pOther->GetTriangleSize() ; ++ nOtId) {
|
||||
// recupero gli indici dei vertici del triangolo
|
||||
int vOId[3] ;
|
||||
|
||||
+16
-35
@@ -94,30 +94,11 @@ typedef std::unordered_map< int, Chain> CHAINMAP ;
|
||||
typedef std::unordered_map< int, TRIA3DVECTOR> TRIA3DVECTORMAP ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Struttura per la ricerca delle T-Junction
|
||||
struct TEdgeId {
|
||||
int nTriaId ;
|
||||
int nEdge ;
|
||||
} ;
|
||||
// Overloading dell'operatore < per TEdgeSet
|
||||
inline bool operator<( const TEdgeId& TEdgeA, const TEdgeId& TEdgeB) {
|
||||
if ( TEdgeA.nTriaId != TEdgeB.nTriaId)
|
||||
return ( TEdgeA.nTriaId < TEdgeB.nTriaId) ;
|
||||
return ( TEdgeA.nEdge < TEdgeB.nEdge) ;
|
||||
}
|
||||
// Loop con T-Junction
|
||||
typedef std::vector<TEdgeId> TJuncLoop ;
|
||||
// Vettore di loop con T-Junction
|
||||
typedef std::vector<TJuncLoop> TJuncLoopVec ;
|
||||
// Set di TEdgeId
|
||||
typedef std::set<TEdgeId> TJEdgeSet ;
|
||||
|
||||
// Definizione strutture intersezione linea-faccia
|
||||
//----------------------------------------------------------------------------
|
||||
// Struttura intersezione linea-faccia
|
||||
struct LineFacetClass {
|
||||
Point3d ptSt, ptEn ;
|
||||
int nTypeA, nTypeB ;
|
||||
LineFacetClass() {
|
||||
LineFacetClass( void) {
|
||||
nTypeA = 0 ;
|
||||
nTypeB = 0 ;
|
||||
}
|
||||
@@ -134,25 +115,24 @@ typedef std::vector<LineFacetClass> LineFacetClassVector ;
|
||||
enum FacetPlaneIntersType { FPI_ERROR = 0, FPI_CUT = 1, FPI_IN = 2, FPI_OUT = 3, FPI_ON = 4 } ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Definizione strutture e contenitori
|
||||
// Contatti interno-interno
|
||||
// Strutture e contenitori contatti interno-interno
|
||||
struct IntersInnSeg {
|
||||
Point3d ptSt ;
|
||||
Point3d ptEn ;
|
||||
Vector3d vtOuter ;
|
||||
IntersInnSeg(void) {
|
||||
IntersInnSeg( void) {
|
||||
;
|
||||
}
|
||||
IntersInnSeg(const Point3d& ptS, const Point3d& ptE) {
|
||||
ptSt = ptS;
|
||||
ptEn = ptE;
|
||||
IntersInnSeg( const Point3d& ptS, const Point3d& ptE) {
|
||||
ptSt = ptS ;
|
||||
ptEn = ptE ;
|
||||
}
|
||||
IntersInnSeg(const Point3d& ptS, const Point3d& ptE, const Vector3d& vtO) {
|
||||
ptSt = ptS;
|
||||
ptEn = ptE;
|
||||
vtOuter = vtO;
|
||||
IntersInnSeg( const Point3d& ptS, const Point3d& ptE, const Vector3d& vtO) {
|
||||
ptSt = ptS ;
|
||||
ptEn = ptE ;
|
||||
vtOuter = vtO ;
|
||||
}
|
||||
};
|
||||
} ;
|
||||
typedef std::vector<IntersInnSeg> IntersInnChain ;
|
||||
typedef std::vector<IntersInnChain> INNCHAINVECTOR ;
|
||||
typedef std::unordered_map<int, IntersInnChain> INTERSCHAINMAP ;
|
||||
@@ -164,7 +144,7 @@ struct IntersEdge {
|
||||
IntersEdge( const Point3d& ptS, const Point3d& ptE, const INTVECTOR& vOFI) {
|
||||
ptSt = ptS;
|
||||
ptEn = ptE;
|
||||
vOthFacetIndex = vOFI;
|
||||
vOthFacetIndex = vOFI ;
|
||||
}
|
||||
} ;
|
||||
typedef std::vector<IntersEdge> IntersEdgeVec ;
|
||||
@@ -305,6 +285,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
||||
INTVECTOR& vTriaIn, INTVECTOR& vTriaOut, INTVECTOR& vTriaOnP, INTVECTOR& vTriaOnM, INTVECTOR& vTriaIndef) override ;
|
||||
bool CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bool bSaveOnEq) override ;
|
||||
bool Repair( double dMaxEdgeLen = MAX_EDGE_LEN_STD) override ;
|
||||
bool GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const override ;
|
||||
const BBox3d& GetAllTriaBox( void) const override ;
|
||||
int GetPartCount( void) const override ;
|
||||
@@ -370,9 +351,9 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool MarchOneTria( int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ;
|
||||
bool VerifyPolylinesForTwoCurves( const PolyLine& PL1, const PolyLine& PL2) const ;
|
||||
bool AddBiTriangle( const int nIdVert[4]) ;
|
||||
bool ResetFaceting( void) ;
|
||||
bool VerifyFaceting( void) const ;
|
||||
bool UpdateFaceting( void) ;
|
||||
bool UpdateOneFace( int nFacet, int nT) ;
|
||||
bool UpdateTriaFaceting( int nRefT, int nFacet, const Plane3d& plPlane, int nT) ;
|
||||
bool SetFacet( int nInd, int nT) ;
|
||||
bool VerifyAdjacTriaFacet( int nT, INTVECTOR& vT) const ;
|
||||
@@ -411,7 +392,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool RemoveTripleTriangles( void) ;
|
||||
bool ScanForTripleTriangles( bool& bModified) ;
|
||||
bool FlipTriangles( int nTA, int nTB) ;
|
||||
bool SimplifyFacets( double dMaxEdgeLen, bool bForced = false) ;
|
||||
bool SimplifyFacets( double dMaxEdgeLen = MAX_EDGE_LEN_STD, bool bForced = true) ;
|
||||
bool AddChainToChain( const Chain& ChainToAdd, PNTVECTOR& OrigChain) ;
|
||||
bool DistPointFacet( const Point3d& ptP, const POLYLINEVECTOR& vPolyVec, double& dPointFacetDist) ;
|
||||
bool ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop) ;
|
||||
|
||||
+56
-122
@@ -1439,122 +1439,6 @@ SurfTriMesh::IdentifyParts( void) const
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::RemoveTJunctions(void)
|
||||
{
|
||||
// Vettore di indici dei vertici sui lati del triangolo corrente
|
||||
unordered_map< int, INTVECTOR> TriaMap ;
|
||||
|
||||
// Ciclo sui triangoli della superficie per determinare gli altri vertici sul loro perimetro
|
||||
for ( int nT = 0 ; nT < int( m_vTria.size()) ; ++ nT) {
|
||||
// Se il triangolo non è valido, passo al successivo
|
||||
Triangle3d trTria ;
|
||||
if ( ! GetTriangle( nT, trTria) || ! trTria.Validate( true))
|
||||
continue ;
|
||||
// Vettore degli altri vertici sul contorno del triangolo
|
||||
INTVECTOR vVertOtl ;
|
||||
// Box del triangolo
|
||||
BBox3d b3Tria ;
|
||||
trTria.GetLocalBBox( b3Tria) ;
|
||||
INTVECTOR vNearTria ;
|
||||
GetAllTriaOverlapBox( b3Tria, vNearTria) ;
|
||||
// Ciclo sui lati del triangolo
|
||||
for ( int nSeg = 0 ; nSeg < 3 ; ++ nSeg) {
|
||||
// aggiungo al vettore il vertice iniziale del lato
|
||||
vVertOtl.emplace_back( m_vTria[nT].nIdVert[nSeg]) ;
|
||||
// Se in questo lato il triangolo è adiacente a un altro, lo salto.
|
||||
if ( m_vTria[nT].nIdAdjac[nSeg] != SVT_DEL && m_vTria[nT].nIdAdjac[nSeg] != SVT_NULL)
|
||||
continue ;
|
||||
int nPrevSize = int( vVertOtl.size()) ;
|
||||
// recupero la geometria del lato
|
||||
Point3d ptSegSt = trTria.GetP( nSeg) ;
|
||||
Point3d ptSegEn = trTria.GetP( ( nSeg + 1) % 3) ;
|
||||
Vector3d vtSeg = ptSegEn - ptSegSt ;
|
||||
double dSegLen = vtSeg.Len() ;
|
||||
if ( dSegLen < EPS_SMALL)
|
||||
continue ;
|
||||
vtSeg /= dSegLen ;
|
||||
// Ciclo sui triangoli vicini
|
||||
for ( int nI = 0 ; nI < int( vNearTria.size()) ; ++ nI) {
|
||||
// Salto il triangolo se è quello di riferimento
|
||||
if ( vNearTria[nI] == nT)
|
||||
continue ;
|
||||
// Cerco i vertici che stanno sul lato del triangolo
|
||||
for ( int nVert = 0 ; nVert < 3 ; ++ nVert) {
|
||||
Point3d ptVert ;
|
||||
if ( ! GetVertex( m_vTria[vNearTria[nI]].nIdVert[nVert], ptVert))
|
||||
continue ;
|
||||
double dProj = ( ptVert - ptSegSt) * vtSeg ;
|
||||
double dOrt = ( ( ptVert - ptSegSt) - dProj * vtSeg).SqLen() ;
|
||||
if ( dProj > EPS_SMALL && dProj < dSegLen - EPS_SMALL && dOrt < SQ_EPS_TRIA_H)
|
||||
vVertOtl.emplace_back( m_vTria[vNearTria[nI]].nIdVert[nVert]) ;
|
||||
}
|
||||
}
|
||||
// Riordino i vertici sul segmento
|
||||
auto SortVerteces = [ this, &ptSegSt, &vtSeg]( const int nV1, const int nV2)
|
||||
{ Point3d ptV1, ptV2 ;
|
||||
GetVertex( nV1, ptV1) ;
|
||||
GetVertex( nV2, ptV2) ;
|
||||
return ( ( ptV1 - ptSegSt) * vtSeg < ( ptV2 - ptSegSt) * vtSeg) ;
|
||||
} ;
|
||||
sort( vVertOtl.begin() + nPrevSize, vVertOtl.end(), SortVerteces) ;
|
||||
}
|
||||
// Se ci sono più di 3 vertici
|
||||
if ( vVertOtl.size() > 3) {
|
||||
// Elimino i vertici ripetuti
|
||||
vVertOtl.erase( unique( vVertOtl.begin(), vVertOtl.end()), vVertOtl.end()) ;
|
||||
// Se ci sono ancora più di 3 vertici, inserisco nel Map
|
||||
if ( vVertOtl.size() > 3)
|
||||
TriaMap.emplace( nT, vVertOtl) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Ciclo sui triangoli da sistemare
|
||||
for ( auto itT = TriaMap.begin() ; itT != TriaMap.end() ; ++ itT) {
|
||||
// Indice del triangolo
|
||||
int nT = itT->first ;
|
||||
// Vettore degli altri vertici sul perimetro
|
||||
const INTVECTOR& vVertOtl = itT->second ;
|
||||
// Se il triangolo non è valido, passo al successivo
|
||||
Triangle3d trTria ;
|
||||
if ( ! GetTriangle( nT, trTria) || ! trTria.Validate( true))
|
||||
continue ;
|
||||
// Rimuovo il triangolo
|
||||
int nTFlag = m_vTria[nT].nTFlag ;
|
||||
RemoveTriangle( nT) ;
|
||||
// Se ci sono 4 vertici, inserisco due triangoli
|
||||
if ( vVertOtl.size() == 4) {
|
||||
// se 1-2-3 è triangolo (e quindi 0-1-3)
|
||||
int nNew1Id[3] = { vVertOtl[1], vVertOtl[2], vVertOtl[3]} ;
|
||||
if ( AddTriangle( nNew1Id, nTFlag) >= 0) {
|
||||
int nNew2Id[3] = { vVertOtl[0], vVertOtl[1], vVertOtl[3]} ;
|
||||
AddTriangle( nNew2Id, nTFlag) ;
|
||||
}
|
||||
// altrimenti 0-1-2 e 2-3-0
|
||||
else {
|
||||
int nNew3Id[3] = { vVertOtl[0], vVertOtl[1], vVertOtl[2]} ;
|
||||
AddTriangle( nNew3Id, nTFlag) ;
|
||||
int nNew4Id[3] = { vVertOtl[2], vVertOtl[3], vVertOtl[0]} ;
|
||||
AddTriangle( nNew4Id, nTFlag) ;
|
||||
}
|
||||
}
|
||||
// altrimenti inserisco un ventaglio di triangoli dal centro ai vertici
|
||||
else {
|
||||
Point3d ptTriaCen = trTria.GetCentroid() ;
|
||||
int nCenIndex = AddVertex( ptTriaCen) ;
|
||||
int nVertNum = int( vVertOtl.size()) ;
|
||||
for ( int nStV = 0 ; nStV < nVertNum ; ++ nStV) {
|
||||
int nEnV = ( nStV + 1) % nVertNum ;
|
||||
int nNewId[3] = { nCenIndex, vVertOtl[nStV], vVertOtl[nEnV]} ;
|
||||
AddTriangle( nNewId, nTFlag) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::RemoveCaps(void)
|
||||
@@ -1763,6 +1647,10 @@ SurfTriMesh::FlipTriangles( int nTA, int nTB)
|
||||
bool
|
||||
SurfTriMesh::Add( const ISurfTriMesh& Other)
|
||||
{
|
||||
// Le superfici devono essere valide
|
||||
if ( ! IsValid() || ! Other.IsValid())
|
||||
return false ;
|
||||
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
SurfTriMesh SurfB ;
|
||||
@@ -1806,8 +1694,7 @@ SurfTriMesh::Add( const ISurfTriMesh& Other)
|
||||
|
||||
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
||||
|
||||
// cerco di semplificare le facce
|
||||
if ( ! SimplifyFacets( 5000.0, true))
|
||||
if ( ! SimplifyFacets())
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Add")
|
||||
|
||||
return bOk ;
|
||||
@@ -1817,6 +1704,10 @@ SurfTriMesh::Add( const ISurfTriMesh& Other)
|
||||
bool
|
||||
SurfTriMesh::Intersect( const ISurfTriMesh& Other)
|
||||
{
|
||||
// Le superfici devono essere valide
|
||||
if ( ! IsValid() || ! Other.IsValid())
|
||||
return false ;
|
||||
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
SurfTriMesh SurfB ;
|
||||
@@ -1860,7 +1751,7 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other)
|
||||
|
||||
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
||||
|
||||
if ( ! SimplifyFacets( 5000.0, true))
|
||||
if ( ! SimplifyFacets())
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect")
|
||||
|
||||
return bOk ;
|
||||
@@ -1870,6 +1761,10 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other)
|
||||
bool
|
||||
SurfTriMesh::Subtract( const ISurfTriMesh& Other)
|
||||
{
|
||||
// Le superfici devono essere valide
|
||||
if ( ! IsValid() || ! Other.IsValid())
|
||||
return false ;
|
||||
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
SurfTriMesh SurfB ;
|
||||
@@ -1914,7 +1809,7 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other)
|
||||
|
||||
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
||||
|
||||
if ( ! SimplifyFacets( 5000.0, true))
|
||||
if ( ! SimplifyFacets())
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect")
|
||||
|
||||
return bOk ;
|
||||
@@ -1925,7 +1820,7 @@ bool
|
||||
SurfTriMesh::GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
||||
INTVECTOR& vTriaIn, INTVECTOR& vTriaOut, INTVECTOR& vTriaOnP, INTVECTOR& vTriaOnM, INTVECTOR& vTriaIndef)
|
||||
{
|
||||
// Le superfici devono essere valide
|
||||
// Le superfici devono essere valide
|
||||
if ( ! IsValid() || ! ClassifierSurf.IsValid())
|
||||
return false ;
|
||||
if ( ClassifierSurf.GetVertexCount() == 0 || ClassifierSurf.GetTriangleCount() == 0)
|
||||
@@ -1975,18 +1870,23 @@ SurfTriMesh::GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
||||
bool
|
||||
SurfTriMesh::CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bool bSaveOnEq)
|
||||
{
|
||||
// Le superfici devono essere valide
|
||||
// Le superfici devono essere valide
|
||||
if ( ! IsValid() || ! CutterSurf.IsValid())
|
||||
return false ;
|
||||
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
SurfTriMesh SurfC ;
|
||||
SurfC.CopyFrom( &CutterSurf) ;
|
||||
|
||||
Frame3d frScalingRef ;
|
||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||
Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||
SurfC.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||
|
||||
IntersectTriMeshTriangle( SurfC) ;
|
||||
IdentifyParts() ;
|
||||
|
||||
int nPartToRemove = ( bInVsOut ? -1 : 1) ;
|
||||
int nCoplanarPartToRemove = ( bSaveOnEq ? ( nPartToRemove ? -2 : 2) : 5) ;
|
||||
int nTriaNum = GetTriangleSize() ;
|
||||
@@ -1994,11 +1894,45 @@ SurfTriMesh::CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bo
|
||||
if ( m_vTria[nT].nTempPart == nPartToRemove || m_vTria[nT].nTempPart == nCoplanarPartToRemove)
|
||||
RemoveTriangle( nT) ;
|
||||
}
|
||||
|
||||
bool bOk = ( AdjustVertices() && DoCompacting()) ;
|
||||
|
||||
bOk = bOk && RemoveTJunctions() ;
|
||||
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||
|
||||
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
||||
|
||||
if ( ! SimplifyFacets())
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::CutWithOtherSurf")
|
||||
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::Repair( double dMaxEdgeLen)
|
||||
{
|
||||
// La superficie deve essere valida
|
||||
if ( ! IsValid())
|
||||
return false ;
|
||||
|
||||
// Forzo aggiornamento grafica
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
// Inserisco triangoli per rimuovere giunzioni a T
|
||||
RemoveTJunctions() ;
|
||||
|
||||
// Sistemo
|
||||
if ( ! AdjustVertices() || ! DoCompacting())
|
||||
return false ;
|
||||
|
||||
// Ritriangolo le facce
|
||||
if ( ! SimplifyFacets( dMaxEdgeLen, true))
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect")
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfTriMesh::VerifyLoopPlane( const PolyLine& ExtLoop, const Plane3d& plCutPlane)
|
||||
|
||||
+2
-2
@@ -57,7 +57,7 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
||||
|
||||
// se superficie originale a facce, cerco di semplificarle in ogni caso
|
||||
if ( nFacetOriCnt < 200 || double( nTriaOriCnt) / nFacetOriCnt > 4) {
|
||||
if ( ! SimplifyFacets( 5000.0))
|
||||
if ( ! SimplifyFacets())
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Cut")
|
||||
}
|
||||
|
||||
@@ -866,7 +866,7 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq)
|
||||
|
||||
// se superficie originale a facce, cerco di semplificarle in ogni caso
|
||||
if ( nFacetOriCnt < 200 || double( nTriaOriCnt) / nFacetOriCnt > 4) {
|
||||
if ( ! SimplifyFacets( 5000.0))
|
||||
if ( ! SimplifyFacets())
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::GeneralizedCut")
|
||||
}
|
||||
|
||||
|
||||
+60
-37
@@ -22,15 +22,6 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::ResetFaceting( void)
|
||||
{
|
||||
m_bFaceted = false ;
|
||||
m_vFacet.clear() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::VerifyFaceting( void) const
|
||||
@@ -44,15 +35,36 @@ SurfTriMesh::VerifyFaceting( void) const
|
||||
bool
|
||||
SurfTriMesh::UpdateFaceting( void)
|
||||
{
|
||||
// salvo vecchio vettore facce
|
||||
INTVECTOR vOldFacet = m_vFacet ;
|
||||
|
||||
// reset faceting
|
||||
m_bFaceted = false ;
|
||||
m_vFacet.clear() ;
|
||||
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i)
|
||||
m_vTria[i].nIdFacet = SVT_NULL ;
|
||||
|
||||
// ricostruisco le sfaccettature
|
||||
bool bOk = true ;
|
||||
// indice faccia corrente
|
||||
int nFacet = -1 ;
|
||||
|
||||
// ricostruisco le sfaccettature come definite in precedenza (dove possibile)
|
||||
bool bOk = true ;
|
||||
for ( int j = 0 ; j < int( vOldFacet.size()) ; ++ j) {
|
||||
int i = vOldFacet[j] ;
|
||||
// salto triangoli inesistenti o già assegnati
|
||||
if ( i >= int( m_vTria.size()) ||
|
||||
m_vTria[i].nIdVert[0] == SVT_DEL ||
|
||||
m_vTria[i].nIdFacet != SVT_NULL)
|
||||
continue ;
|
||||
// assegno indice di faccia al triangolo
|
||||
m_vTria[i].nIdFacet = ++ nFacet ;
|
||||
m_vFacet.push_back( i) ;
|
||||
// aggiorno faccia
|
||||
if ( ! UpdateOneFace( nFacet, i))
|
||||
bOk = false ;
|
||||
}
|
||||
|
||||
// ricostruisco le altre sfaccettature
|
||||
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) {
|
||||
// salto triangoli cancellati o già assegnati
|
||||
if ( m_vTria[i].nIdVert[0] == SVT_DEL ||
|
||||
@@ -61,32 +73,9 @@ SurfTriMesh::UpdateFaceting( void)
|
||||
// assegno indice di faccia al triangolo
|
||||
m_vTria[i].nIdFacet = ++ nFacet ;
|
||||
m_vFacet.push_back( i) ;
|
||||
// piano del triangolo
|
||||
Plane3d plPlane ;
|
||||
if ( ! plPlane.Set( m_vVert[m_vTria[i].nIdVert[0]].ptP, m_vTria[i].vtN)) {
|
||||
LOG_ERROR( GetEGkLogger(), "SurfTM : UpdateFaceting error in triangle data")
|
||||
return false ;
|
||||
}
|
||||
// set di triangoli da aggiornare
|
||||
set<int> stTria ;
|
||||
stTria.insert( i) ;
|
||||
// finchè set non vuoto
|
||||
while ( ! stTria.empty()) {
|
||||
// tolgo un triangolo dal set
|
||||
const auto iIt = stTria.begin() ;
|
||||
int nT = *iIt ;
|
||||
stTria.erase( iIt) ;
|
||||
// aggiorno i triangoli adiacenti
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
int nAdjT = m_vTria[nT].nIdAdjac[j] ;
|
||||
if ( nAdjT != SVT_NULL && m_vTria[nAdjT].nIdFacet == SVT_NULL) {
|
||||
if ( ! UpdateTriaFaceting( nT, nFacet, plPlane, nAdjT))
|
||||
bOk = false ;
|
||||
if ( m_vTria[nAdjT].nIdFacet == nFacet)
|
||||
stTria.insert( nAdjT) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// aggiorno faccia
|
||||
if ( ! UpdateOneFace( nFacet, i))
|
||||
bOk = false ;
|
||||
}
|
||||
|
||||
// se ci sono stati problemi, salvo nel log
|
||||
@@ -98,6 +87,40 @@ SurfTriMesh::UpdateFaceting( void)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::UpdateOneFace( int nFacet, int nT)
|
||||
{
|
||||
// piano del triangolo
|
||||
Plane3d plPlane ;
|
||||
if ( ! plPlane.Set( m_vVert[m_vTria[nT].nIdVert[0]].ptP, m_vTria[nT].vtN)) {
|
||||
LOG_ERROR( GetEGkLogger(), "SurfTM : UpdateFaceting error in triangle data")
|
||||
return false ;
|
||||
}
|
||||
// set di triangoli da aggiornare
|
||||
set<int> stTria ;
|
||||
stTria.insert( nT) ;
|
||||
// finchè set non vuoto
|
||||
bool bOk = true ;
|
||||
while ( ! stTria.empty()) {
|
||||
// tolgo un triangolo dal set
|
||||
const auto iIt = stTria.begin() ;
|
||||
int nT = *iIt ;
|
||||
stTria.erase( iIt) ;
|
||||
// aggiorno i triangoli adiacenti
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
int nAdjT = m_vTria[nT].nIdAdjac[j] ;
|
||||
if ( nAdjT != SVT_NULL && m_vTria[nAdjT].nIdFacet == SVT_NULL) {
|
||||
if ( ! UpdateTriaFaceting( nT, nFacet, plPlane, nAdjT))
|
||||
bOk = false ;
|
||||
if ( m_vTria[nAdjT].nIdFacet == nFacet)
|
||||
stTria.insert( nAdjT) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::UpdateTriaFaceting( int nRefT, int nFacet, const Plane3d& plPlane, int nT)
|
||||
|
||||
+147
-4
@@ -19,6 +19,141 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::RemoveTJunctions(void)
|
||||
{
|
||||
// Vettore di indici dei vertici sui lati del triangolo corrente
|
||||
unordered_map< int, INTVECTOR> TriaMap ;
|
||||
|
||||
// Ciclo sui triangoli della superficie per determinare gli altri vertici sul loro perimetro
|
||||
for ( int nT = 0 ; nT < int( m_vTria.size()) ; ++ nT) {
|
||||
// Se il triangolo non è valido, passo al successivo
|
||||
Triangle3d trTria ;
|
||||
if ( ! GetTriangle( nT, trTria) || ! trTria.Validate( true))
|
||||
continue ;
|
||||
// Vettore degli altri vertici sul contorno del triangolo
|
||||
INTVECTOR vVertOtl ;
|
||||
// Box del triangolo
|
||||
BBox3d b3Tria ;
|
||||
trTria.GetLocalBBox( b3Tria) ;
|
||||
INTVECTOR vNearTria ;
|
||||
GetAllTriaOverlapBox( b3Tria, vNearTria) ;
|
||||
// Ciclo sui lati del triangolo
|
||||
for ( int nSeg = 0 ; nSeg < 3 ; ++ nSeg) {
|
||||
// aggiungo al vettore il vertice iniziale del lato
|
||||
vVertOtl.emplace_back( m_vTria[nT].nIdVert[nSeg]) ;
|
||||
// Se in questo lato il triangolo è adiacente a un altro, lo salto.
|
||||
if ( m_vTria[nT].nIdAdjac[nSeg] != SVT_DEL && m_vTria[nT].nIdAdjac[nSeg] != SVT_NULL)
|
||||
continue ;
|
||||
int nPrevSize = int( vVertOtl.size()) ;
|
||||
// recupero la geometria del lato
|
||||
Point3d ptSegSt = trTria.GetP( nSeg) ;
|
||||
Point3d ptSegEn = trTria.GetP( ( nSeg + 1) % 3) ;
|
||||
Vector3d vtSeg = ptSegEn - ptSegSt ;
|
||||
double dSegLen = vtSeg.Len() ;
|
||||
if ( dSegLen < EPS_SMALL)
|
||||
continue ;
|
||||
vtSeg /= dSegLen ;
|
||||
// Ciclo sui triangoli vicini
|
||||
for ( int nI = 0 ; nI < int( vNearTria.size()) ; ++ nI) {
|
||||
// Salto il triangolo se è quello di riferimento
|
||||
if ( vNearTria[nI] == nT)
|
||||
continue ;
|
||||
// Cerco i vertici che stanno sul lato del triangolo
|
||||
for ( int nVert = 0 ; nVert < 3 ; ++ nVert) {
|
||||
Point3d ptVert ;
|
||||
if ( ! GetVertex( m_vTria[vNearTria[nI]].nIdVert[nVert], ptVert))
|
||||
continue ;
|
||||
double dProj = ( ptVert - ptSegSt) * vtSeg ;
|
||||
double dOrt = ( ( ptVert - ptSegSt) - dProj * vtSeg).SqLen() ;
|
||||
if ( dProj > EPS_SMALL && dProj < dSegLen - EPS_SMALL && dOrt < SQ_EPS_TRIA_H)
|
||||
vVertOtl.emplace_back( m_vTria[vNearTria[nI]].nIdVert[nVert]) ;
|
||||
}
|
||||
}
|
||||
// Riordino i vertici sul segmento
|
||||
auto SortVerteces = [ this, &ptSegSt, &vtSeg]( const int nV1, const int nV2)
|
||||
{ Point3d ptV1, ptV2 ;
|
||||
GetVertex( nV1, ptV1) ;
|
||||
GetVertex( nV2, ptV2) ;
|
||||
return ( ( ptV1 - ptSegSt) * vtSeg < ( ptV2 - ptSegSt) * vtSeg) ;
|
||||
} ;
|
||||
sort( vVertOtl.begin() + nPrevSize, vVertOtl.end(), SortVerteces) ;
|
||||
}
|
||||
// Se ci sono più di 3 vertici
|
||||
if ( vVertOtl.size() > 3) {
|
||||
// Elimino i vertici ripetuti
|
||||
vVertOtl.erase( unique( vVertOtl.begin(), vVertOtl.end()), vVertOtl.end()) ;
|
||||
// Se ci sono ancora più di 3 vertici, inserisco nel Map
|
||||
if ( vVertOtl.size() > 3)
|
||||
TriaMap.emplace( nT, vVertOtl) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Ciclo sui triangoli da sistemare
|
||||
for ( auto itT = TriaMap.begin() ; itT != TriaMap.end() ; ++ itT) {
|
||||
// Indice del triangolo
|
||||
int nT = itT->first ;
|
||||
// Vettore degli altri vertici sul perimetro
|
||||
const INTVECTOR& vVertOtl = itT->second ;
|
||||
// Se il triangolo non è valido, passo al successivo
|
||||
Triangle3d trTria ;
|
||||
if ( ! GetTriangle( nT, trTria) || ! trTria.Validate( true))
|
||||
continue ;
|
||||
// Salvo eventuale indice di faccetta
|
||||
int nFacet = m_vTria[nT].nIdFacet ;
|
||||
if ( nFacet > int( m_vFacet.size()) || m_vFacet[nFacet] != nT)
|
||||
nFacet = SVT_NULL ;
|
||||
// Rimuovo il triangolo
|
||||
int nTFlag = m_vTria[nT].nTFlag ;
|
||||
RemoveTriangle( nT) ;
|
||||
// Aggiungo i nuovi triangoli
|
||||
int nLastNewTria = SVT_NULL ;
|
||||
// Se ci sono 4 vertici, inserisco due triangoli
|
||||
if ( vVertOtl.size() == 4) {
|
||||
// se 1-2-3 è triangolo (e quindi 0-1-3)
|
||||
int nNew1Id[3] = { vVertOtl[1], vVertOtl[2], vVertOtl[3]} ;
|
||||
int nNew1Tria = AddTriangle( nNew1Id, nTFlag) ;
|
||||
if ( nNew1Tria != SVT_NULL && nNew1Tria != SVT_DEL) {
|
||||
nLastNewTria = nNew1Tria ;
|
||||
int nNew2Id[3] = { vVertOtl[0], vVertOtl[1], vVertOtl[3]} ;
|
||||
int nNew2Tria = AddTriangle( nNew2Id, nTFlag) ;
|
||||
if ( nNew2Tria != SVT_NULL && nNew2Tria != SVT_DEL)
|
||||
nLastNewTria = nNew2Tria ;
|
||||
}
|
||||
// altrimenti 0-1-2 e 2-3-0
|
||||
else {
|
||||
int nNew3Id[3] = { vVertOtl[0], vVertOtl[1], vVertOtl[2]} ;
|
||||
int nNew3Tria = AddTriangle( nNew3Id, nTFlag) ;
|
||||
if ( nNew3Tria != SVT_NULL && nNew3Tria != SVT_DEL)
|
||||
nLastNewTria = nNew3Tria ;
|
||||
int nNew4Id[3] = { vVertOtl[2], vVertOtl[3], vVertOtl[0]} ;
|
||||
int nNew4Tria = AddTriangle( nNew4Id, nTFlag) ;
|
||||
if ( nNew4Tria != SVT_NULL && nNew4Tria != SVT_DEL)
|
||||
nLastNewTria = nNew4Tria ;
|
||||
}
|
||||
}
|
||||
// altrimenti inserisco un ventaglio di triangoli dal centro ai vertici
|
||||
else {
|
||||
Point3d ptTriaCen = trTria.GetCentroid() ;
|
||||
int nCenIndex = AddVertex( ptTriaCen) ;
|
||||
int nVertNum = int( vVertOtl.size()) ;
|
||||
for ( int nStV = 0 ; nStV < nVertNum ; ++ nStV) {
|
||||
int nEnV = ( nStV + 1) % nVertNum ;
|
||||
int nNewId[3] = { nCenIndex, vVertOtl[nStV], vVertOtl[nEnV]} ;
|
||||
int nNewTria = AddTriangle( nNewId, nTFlag) ;
|
||||
if ( nNewTria != SVT_NULL && nNewTria != SVT_DEL)
|
||||
nLastNewTria = nNewTria ;
|
||||
}
|
||||
}
|
||||
// Eventuale aggiustamento per indice di faccetta
|
||||
if ( nFacet != SVT_NULL && nLastNewTria != SVT_NULL)
|
||||
m_vFacet[nFacet] = nLastNewTria ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
IsVertex( PNTULIST& PointList, PNTULIST::const_iterator itCurr)
|
||||
@@ -168,8 +303,8 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
||||
// La trimesh deve essere valida
|
||||
if ( ! IsValid())
|
||||
return false ;
|
||||
// Se la lunghezza massima del lato del triangolo sul bordo della faccia è nulla, non devo fare alcunché
|
||||
if ( dMaxEdgeLen < EPS_SMALL)
|
||||
// Se la lunghezza massima del lato del triangolo sul bordo della faccia è nulla e non forzata, non devo fare alcunché
|
||||
if ( dMaxEdgeLen < EPS_SMALL && ! bForced)
|
||||
return true ;
|
||||
|
||||
// Recupero il numero delle facce (esegue anche una verifica delle stesse)
|
||||
@@ -202,7 +337,7 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
||||
bToRetriangulate = true ;
|
||||
}
|
||||
|
||||
// Se non richiesta ritriangolazione dai bordi, verifico se ci sono vertici di triangoli interni
|
||||
// Se non richiesta ritriangolazione dai bordi, verifico se ci sono vertici di triangoli interni (*** disabilitato ***)
|
||||
if ( false && ! bToRetriangulate) {
|
||||
// numero dei triangoli nella faccia
|
||||
INTVECTOR vFacetTria ;
|
||||
@@ -214,7 +349,7 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
||||
nSideCnt += LoopVec[nL].GetLineNbr() ;
|
||||
// numero dei buchi della faccia
|
||||
int nHoleCnt = int( LoopVec.size()) - 1 ;
|
||||
// dalla formula di Eulero adattata al caso ( nTriaCnt = nSideCnt + 2 * ( nHoleCnt -1))
|
||||
// dalla formula di Eulero adattata al caso ( nTriaCnt = nSideCnt + 2 * ( nHoleCnt - 1))
|
||||
if ( nTriaCnt != nSideCnt + 2 * ( nHoleCnt - 1))
|
||||
bToRetriangulate = true ;
|
||||
}
|
||||
@@ -253,6 +388,7 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
||||
const PNTVECTOR& vPt = itF->second.first ;
|
||||
const INTVECTOR& vTr = itF->second.second ;
|
||||
// Inserisco i nuovi triangoli
|
||||
bool bFirstTria = true ;
|
||||
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||
int nNewId[3] = { AddVertex( vPt[vTr[n]]),
|
||||
AddVertex( vPt[vTr[n + 1]]),
|
||||
@@ -260,6 +396,13 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
||||
auto itCol = ColorMap.find( itF->first) ;
|
||||
int nTFlag = ( itCol != ColorMap.end() ? itCol->second : 0) ;
|
||||
int nNewTriaId = AddTriangle( nNewId, nTFlag) ;
|
||||
if ( nNewTriaId != SVT_NULL && nNewTriaId != SVT_DEL) {
|
||||
m_vTria[nNewTriaId].nIdFacet = itF->first ;
|
||||
if ( bFirstTria) {
|
||||
m_vFacet[itF->first] = nNewTriaId ;
|
||||
bFirstTria = false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -342,9 +342,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
|
||||
|
||||
// Intersezioni
|
||||
bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax) const ;
|
||||
bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax,
|
||||
double& dU1, double& dU2) const ;
|
||||
bool IntersLineZMapLattice( const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) const ;
|
||||
bool IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) const ;
|
||||
bool IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, int nGrid, int nI, int nJ,
|
||||
|
||||
+7
-102
@@ -16,10 +16,12 @@
|
||||
#include "CurveLine.h"
|
||||
#include "VolZmap.h"
|
||||
#include "GeoConst.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "IntersLineSurfStd.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSphere.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlaneBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlaneTria.h"
|
||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
@@ -30,103 +32,6 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Box e piano devono essere nello stesso riferimento. Il box deve essere axis aligned.
|
||||
static bool
|
||||
TestIntersPlaneBox( const BBox3d& b3Box, const Plane3d& plPlane)
|
||||
{
|
||||
// Calcolo le distanze con segno dei punti dal piano
|
||||
Point3d ptE0 = b3Box.GetMin() ;
|
||||
double dDist0 = DistPointPlane( ptE0, plPlane) ;
|
||||
Point3d ptE1( b3Box.GetMax().x, b3Box.GetMin().y, b3Box.GetMin().z) ;
|
||||
double dDist1 = DistPointPlane( ptE1, plPlane) ;
|
||||
Point3d ptE2( b3Box.GetMax().x, b3Box.GetMax().y, b3Box.GetMin().z) ;
|
||||
double dDist2 = DistPointPlane( ptE2, plPlane) ;
|
||||
Point3d ptE3( b3Box.GetMin().x, b3Box.GetMax().y, b3Box.GetMin().z) ;
|
||||
double dDist3 = DistPointPlane( ptE3, plPlane) ;
|
||||
Point3d ptE4( b3Box.GetMin().x, b3Box.GetMin().y, b3Box.GetMax().z) ;
|
||||
double dDist4 = DistPointPlane( ptE4, plPlane) ;
|
||||
Point3d ptE5( b3Box.GetMax().x, b3Box.GetMin().y, b3Box.GetMax().z) ;
|
||||
double dDist5 = DistPointPlane( ptE5, plPlane) ;
|
||||
Point3d ptE6 = b3Box.GetMax() ;
|
||||
double dDist6 = DistPointPlane( ptE6, plPlane) ;
|
||||
Point3d ptE7( b3Box.GetMin().x, b3Box.GetMax().y, b3Box.GetMax().z) ;
|
||||
double dDist7 = DistPointPlane( ptE7, plPlane) ;
|
||||
// Distanze tutte positive
|
||||
if ( dDist0 > EPS_SMALL && dDist1 > EPS_SMALL && dDist2 > EPS_SMALL && dDist3 > EPS_SMALL &&
|
||||
dDist4 > EPS_SMALL && dDist5 > EPS_SMALL && dDist6 > EPS_SMALL && dDist7 > EPS_SMALL)
|
||||
return false ;
|
||||
// Distanze tutte negative
|
||||
if ( dDist0 < - EPS_SMALL && dDist1 < - EPS_SMALL && dDist2 < - EPS_SMALL && dDist3 < - EPS_SMALL &&
|
||||
dDist4 < - EPS_SMALL && dDist5 < - EPS_SMALL && dDist6 < - EPS_SMALL && dDist7 < - EPS_SMALL)
|
||||
return false ;
|
||||
// Il piano interseca il box
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Punti e vettore devono esse espressi nel medesimo sistema di riferimento.
|
||||
// Il box è allineato con gli assi di tale sistema di riferimento.
|
||||
// Viene restituito true in caso di intersezione, false altrimenti.
|
||||
bool
|
||||
VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax) const
|
||||
{
|
||||
double dU1, dU2 ;
|
||||
return IntersLineBox( ptP, vtV, ptMin, ptMax, dU1, dU2) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Punti e vettore devono esse espressi nel medesimo sistema di riferimento.
|
||||
// Il box è allineato con gli assi di tale sistema di riferimento.
|
||||
// In dU1, dU2 vengono restituiti i parametri a cui si trovano le intersezioni.
|
||||
// Viene restituito true in caso di intersezione, false altrimenti.
|
||||
bool
|
||||
VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
|
||||
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) const
|
||||
{
|
||||
// Il box è allineato agli assi
|
||||
dU1 = - INFINITO ;
|
||||
dU2 = INFINITO ;
|
||||
|
||||
// confronto con piani YZ (perpendicolari ad asse X)
|
||||
if ( vtV.x > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ;
|
||||
dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ;
|
||||
}
|
||||
else if ( vtV.x < - EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ;
|
||||
dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ;
|
||||
}
|
||||
else if ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// confronto con piani ZX (perpendicolari ad asse Y)
|
||||
if ( vtV.y > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ;
|
||||
dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ;
|
||||
}
|
||||
else if ( vtV.y < - EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ;
|
||||
dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ;
|
||||
}
|
||||
else if ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// confronto con piani XY (perpendicolari ad asse Z)
|
||||
if ( vtV.z > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ;
|
||||
dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ;
|
||||
}
|
||||
else if ( vtV.z < - EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ;
|
||||
dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ;
|
||||
}
|
||||
else if ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
return ( dU2 >= dU1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// La retta è rappresentata da un punto e dal versore espressi nel riferimento dello Zmap.
|
||||
// Se non vi è intersezione, viene restituito falso
|
||||
@@ -3188,7 +3093,7 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
|
||||
if ( ! GetBlockBox( nBlockIJK, b3BlockBox))
|
||||
return false ;
|
||||
// Se c'è intersezione valuto tutti i voxel interni
|
||||
if ( IntersLineBox( ptLocP, vtDirL, b3BlockBox.GetMin(), b3BlockBox.GetMax())) {
|
||||
if ( TestIntersLineBox( ptLocP, vtDirL, b3BlockBox.GetMin(), b3BlockBox.GetMax())) {
|
||||
// Ciclo sui voxel del blocco.
|
||||
// Triangoli smooth
|
||||
for ( int nV = 0 ; nV < int( m_BlockSmoothTria[nB].size()) ; ++ nV) {
|
||||
@@ -3199,7 +3104,7 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
|
||||
m_BlockSmoothTria[nB][nV].k } ;
|
||||
GetVoxelBox( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], b3Vox) ;
|
||||
// Se non c'è intersezione col voxel, passo al successivo.
|
||||
if ( ! IntersLineBox( ptLocP, vtDirL, b3Vox.GetMin(), b3Vox.GetMax()))
|
||||
if ( ! TestIntersLineBox( ptLocP, vtDirL, b3Vox.GetMin(), b3Vox.GetMax()))
|
||||
continue ;
|
||||
for ( int nT = 0 ; nT < int( m_BlockSmoothTria[nB][nV].vTria.size()) ; ++ nT) {
|
||||
Triangle3d trTria = m_BlockSmoothTria[nB][nV].vTria[nT] ;
|
||||
@@ -3374,7 +3279,7 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c
|
||||
if ( ! GetBlockBox( nBlockIJK, b3BlockBox))
|
||||
return false ;
|
||||
// Se c'è intersezione valuto tutti i voxel interni
|
||||
if ( TestIntersPlaneBox( b3BlockBox, plPlaneLoc)) {
|
||||
if ( TestIntersPlaneBox( plPlaneLoc, b3BlockBox)) {
|
||||
// Ciclo sui voxel del blocco.
|
||||
// Triangoli smooth
|
||||
for ( int nV = 0 ; nV < int( m_BlockSmoothTria[nB].size()) ; ++ nV) {
|
||||
@@ -3382,7 +3287,7 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c
|
||||
BBox3d b3Vox ;
|
||||
GetVoxelBox( m_BlockSmoothTria[nB][nV].i, m_BlockSmoothTria[nB][nV].j, m_BlockSmoothTria[nB][nV].k, b3Vox) ;
|
||||
// Se non c'è intersezione col voxel, passo al successivo.
|
||||
if ( ! TestIntersPlaneBox(b3Vox, plPlaneLoc))
|
||||
if ( ! TestIntersPlaneBox( plPlaneLoc, b3Vox))
|
||||
continue ;
|
||||
for ( int nT = 0 ; nT < int( m_BlockSmoothTria[nB][nV].vTria.size()) ; ++ nT) {
|
||||
Triangle3d trTria = m_BlockSmoothTria[nB][nV].vTria[nT] ;
|
||||
@@ -3486,5 +3391,5 @@ bool
|
||||
VolZmap::TestIntersPlaneZmapBBox( const Plane3d& plPlane) const
|
||||
{
|
||||
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
|
||||
return TestIntersPlaneBox( b3Zmap, plPlane) ;
|
||||
return TestIntersPlaneBox( plPlane, b3Zmap) ;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "GeoConst.h"
|
||||
#include "MC_Tables.h"
|
||||
#include "PolygonPlane.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||
|
||||
Reference in New Issue
Block a user