EgtGeomKernel :

- in VolZmap GetFeatureChaines rinominata in GetEdges e molto migliorata.
This commit is contained in:
Dario Sassi
2019-09-12 18:40:32 +00:00
parent bd1efafbc0
commit c630263e5c
4 changed files with 171 additions and 165 deletions
+4 -4
View File
@@ -2711,8 +2711,8 @@ GdbExecutor::ExecuteVolZmap( const string& sCmd2, const STRVECTOR& vsParams)
else if ( sCmd2 == "COMP") {
return ExecuteVolZmapCompact( vsParams) ;
}
else if ( sCmd2 == "CHAIN") {
return ExecuteVolZmapChain( vsParams) ;
else if ( sCmd2 == "EDGES") {
return ExecuteVolZmapEdges( vsParams) ;
}
return false ;
}
@@ -3072,7 +3072,7 @@ GdbExecutor::ExecuteVolZmapCompact( const STRVECTOR& vsParams)
//----------------------------------------------------------------------------
bool
GdbExecutor::ExecuteVolZmapChain(const STRVECTOR& vsParams)
GdbExecutor::ExecuteVolZmapEdges(const STRVECTOR& vsParams)
{
// Parametri : ZmapId, ParentId
if ( vsParams.size() != 2)
@@ -3087,7 +3087,7 @@ GdbExecutor::ExecuteVolZmapChain(const STRVECTOR& vsParams)
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
return false ;
ICURVEPOVECTOR vpLoop ;
pZmap->GetFeatureChaines( vpLoop) ;
pZmap->GetEdges( vpLoop) ;
bool bOk = true ;
for ( int n = 0 ; n < int( vpLoop.size()) && bOk ; ++ n) {
bOk = bOk && AddGeoObj( "$NN", vsParams[1], Release( vpLoop[n])) ;
+1 -1
View File
@@ -129,7 +129,7 @@ class GdbExecutor : public IGdbExecutor
//bool VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams) ;
bool ExecuteVolZmapCut( const STRVECTOR& vsParams) ;
bool ExecuteVolZmapCompact( const STRVECTOR& vsParams) ;
bool ExecuteVolZmapChain( const STRVECTOR& vsParams) ;
bool ExecuteVolZmapEdges( const STRVECTOR& vsParams) ;
bool ExecuteIntersection( const std::string& sCmd2, const STRVECTOR& vsParams) ;
bool LineDiscInters( const STRVECTOR& vsParams) ;
bool RayDiscInters( const STRVECTOR& vsParams) ;
+1 -1
View File
@@ -71,6 +71,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
int GetBlockCount( void) const override ;
int GetBlockUpdatingCounter( int nBlock) const override ;
bool GetBlockTriangles( int nBlock, TRIA3DEXVECTOR& vTria) const override ;
bool GetEdges( ICURVEPOVECTOR& vpCurve) const override ;
bool GetVolume( double& dVol) const override ;
int GetPartCount( void) const override ;
bool GetPartVolume( int nPart, double& dVol) const override ;
@@ -93,7 +94,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW
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 GetFeatureChaines( ICURVEPOVECTOR& vpCurve) const ;
bool AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist) const override ;
bool AvoidSphere( const Point3d& ptCenter, double dRad, double dSafeDist) const override ;
bool AvoidCylinder( const Frame3d& frCyl, double dH, double dR, double dSafeDist) const override ;
+165 -159
View File
@@ -1026,8 +1026,8 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
// Ciclo su tutti i voxel del blocco
for ( int i = nLimits[0] ; i < nLimits[1] ; ++ i) {
for ( int j = nLimits[2] ; j < nLimits[3] ; ++ j) {
for ( int k = nLimits[4] ; k < nLimits[5] ; ++ k) {
for ( int k = nLimits[4] ; k < nLimits[5] ; ++ k) {
if ( m_nShape == BOX && ! IsVoxelOnBoxEdge( i, j, k))
continue ;
// Classificazione dei vertici: interni o esterni al materiale
@@ -2599,7 +2599,11 @@ VolZmap::CreateSharpFeatureTriangle( int nBlock, const VoxelContainer& vVoxel) c
CurrTri.SetGrade( 0) ;
// Setto le normali a ogni vertice
CurrTri.SetVertexNorm( 1, it->second.Compo[nComp].CompVecField[nNextVert].vtVec) ;
CurrTri.SetVertexNorm( 2, it->second.Compo[nComp].CompVecField[nVert].vtVec) ;
CurrTri.SetVertexNorm( 2, it->second.Compo[nComp].CompVecField[nVert].vtVec) ;
// Setto i flag a false
CurrTri.SetEdgeFlag( 0, false) ;
CurrTri.SetEdgeFlag( 1, false) ;
CurrTri.SetEdgeFlag( 2, false) ;
// Valido il triangolo
if ( ! CurrTri.Validate( true))
CurrTri.SetVertexNorm( 0, 0.5 * ( CurrTri.GetVertexNorm( 1) + CurrTri.GetVertexNorm( 2))) ;
@@ -2661,8 +2665,12 @@ VolZmap::CreateSharpFeatureTriangle( int nBlock, const VoxelContainer& vVoxel) c
// Setto le normali a ogni vertice
CurrTri.SetVertexNorm( 1, itVox->second.Compo[nComp].CompVecField[nNextVert].vtVec) ;
CurrTri.SetVertexNorm( 2, itVox->second.Compo[nComp].CompVecField[nVert].vtVec) ;
// Setto i flag a false
CurrTri.SetEdgeFlag( 0, false) ;
CurrTri.SetEdgeFlag( 1, false) ;
CurrTri.SetEdgeFlag( 2, false) ;
// Valido il triangolo
if ( ! CurrTri.Validate(true))
if ( ! CurrTri.Validate( true))
CurrTri.SetVertexNorm( 0, 0.5 * ( CurrTri.GetVertexNorm( 1) + CurrTri.GetVertexNorm( 2)));
// Smisto i triangoli fra di frontiera e interni
bool bTriOnBorder = IsTriangleOnBorder( CurrTri, nLimits, nVoxIJK) ;
@@ -2917,6 +2925,13 @@ VolZmap::FlipEdgesII( int nBlock) const
vTria1[nTri1].SetVertexNorm( 1, V_NULL) ;
vTria2[nTri2].SetVertexNorm( 0, V_NULL) ;
vTria2[nTri2].SetVertexNorm( 1, V_NULL) ;
// Valido i triangoli
vTria1[nTri1].Validate( true) ;
vTria2[nTri2].Validate( true) ;
// Setto i bFlags
if ( ! AreSameVectorApprox( vTria1[nTri1].GetN(), vTria2[nTri2].GetN())) {
vTria1[nTri1].SetEdgeFlag( 0, true) ;
}
// Setto i triangoli come flippati
SharpTria1.vbFlipped[nCompo1][nTri1] = true ;
SharpTria2.vbFlipped[nCompo2][nTri2] = true ;
@@ -2961,6 +2976,19 @@ VolZmap::FlipEdgesII( int nBlock) const
// Assegno il colore ai triangoli
vTria1[nTri1].SetGrade( nCol) ;
vTria2[nTri2].SetGrade( nCol) ;
// Setto i flag dei vertici
double dDist02 = ( vTria1[nTri1].GetP( 0) - vTria1[nTri1].GetP( 2)).Len() +
( vTria2[nTri2].GetP( 1) - vTria2[nTri2].GetP( 0)).Len() ;
double dDist20 = ( vTria1[nTri1].GetP( 1) - vTria1[nTri1].GetP( 0)).Len() +
( vTria2[nTri2].GetP( 0) - vTria2[nTri2].GetP( 2)).Len() ;
if ( dDist02 > dDist20) {
vTria1[nTri1].SetEdgeFlag( 0, true) ;
vTria2[nTri2].SetEdgeFlag( 2, true) ;
}
else {
vTria1[nTri1].SetEdgeFlag( 2, true) ;
vTria2[nTri2].SetEdgeFlag( 0, true) ;
}
}
}
}
@@ -3182,6 +3210,14 @@ VolZmap::FlipEdgesBB() const
m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetVertexNorm( 0, vtNormF) ;
m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( 1, vtNormL) ;
m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( 0, vtNormL) ;
// Valido i triangoli
m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].Validate( true) ;
m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].Validate( true) ;
// Setto i bFlags
if ( ! AreSameVectorApprox( m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetN(),
m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetN())) {
m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetEdgeFlag( 0, true) ;
}
// Setto i triangoli come flippati
m_InterBlockSharpTria[tFB][tVFB].vbFlipped[tCmpF][tTriFB] = true ;
m_InterBlockSharpTria[tLB][tVLB].vbFlipped[tCmpL][tTriLB] = true ;
@@ -3229,6 +3265,23 @@ VolZmap::FlipEdgesBB() const
// Assegno il colore ai triangoli
m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetGrade( nCol) ;
m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetGrade( nCol) ;
// Setto i flag dei vertici
double dDist02 = ( m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 0) -
m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 2)).Len() +
( m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 1) -
m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 0)).Len() ;
double dDist20 = ( m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 1) -
m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 0)).Len() +
( m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 0) -
m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 2)).Len() ;
if ( dDist02 > dDist20) {
m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetEdgeFlag( 0, true) ;
m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetEdgeFlag( 2, true) ;
}
else {
m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetEdgeFlag( 2, true) ;
m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetEdgeFlag( 0, true) ;
}
}
}
}
@@ -4457,181 +4510,134 @@ VolZmap::Remove( FlatVoxelContainer& VoxCont, int nI, int nJ, int nK) const
//----------------------------------------------------------------------------
bool
VolZmap::GetFeatureChaines( ICURVEPOVECTOR& vpCurve) const
VolZmap::GetEdges( ICURVEPOVECTOR& vpCurve) const
{
// Garantisco grafica aggiornata
UpdateTripleMapGraphics() ;
// Vettore delle curve di feature
vector<CurveComposite> vLine ;
// Vettore dei segmenti di feature (coppie di punti)
BIPNTVECTOR vBpt ;
// Ciclo sui triangoli feature all'interno dei blocchi
for ( int nBlock = 0 ; nBlock < m_nNumBlock ; ++ nBlock) {
// Numero di voxel in cui si presentano sharp feature
int nVoxelNum = int( m_BlockSharpTria[nBlock].size()) ;
int nVoxelNum = int( m_BlockSharpTria[nBlock].size()) ;
// Ciclo sui voxel con sharp feature
for ( int n1 = 0 ; n1 < nVoxelNum ; ++ n1) {
const SharpTriaStruct& SharpTria1 = m_BlockSharpTria[nBlock][n1] ;
for ( int n2 = n1 ; n2 < nVoxelNum ; ++ n2) {
const SharpTriaStruct& SharpTria2 = m_BlockSharpTria[nBlock][n2] ;
// Se non adiacenti o coincidenti vado oltre
if ( abs( SharpTria2.i - SharpTria1.i) > 1 ||
abs( SharpTria2.j - SharpTria1.j) > 1 ||
abs( SharpTria2.k - SharpTria1.k) > 1)
continue ;
// Ciclo sulle componenti connesse del primo voxel
int nNumCompo1 = int( SharpTria1.ptCompoVert.size()) ;
for ( int nCompo1 = 0 ; nCompo1 < nNumCompo1 ; ++ nCompo1) {
const TRIA3DEXVECTOR& vTria1 = SharpTria1.vCompoTria[nCompo1] ;
// Numero di triangoli della componente connessa
int nTriNum1 = int( vTria1.size()) ;
// Ciclo sulle componenti connesse del secondo voxel
int nNumCompo2 = int( SharpTria2.ptCompoVert.size()) ;
int nCompo2 = ( n1 == n2 ? nCompo1 + 1 : 0) ;
for ( ; nCompo2 < nNumCompo2 ; ++ nCompo2) {
const TRIA3DEXVECTOR& vTria2 = SharpTria2.vCompoTria[nCompo2] ;
// Numero di triangoli della componente connessa
int nTriNum2 = int( vTria2.size()) ;
for ( int nTri1 = 0 ; nTri1 < nTriNum1 ; ++ nTri1) {
for ( int nTri2 = 0 ; nTri2 < nTriNum2 ; ++ nTri2) {
// Punti che devono essere in comune fra i due triangoli
const Point3d& ptP10 = vTria1[nTri1].GetP( 0) ;
const Point3d& ptP11 = vTria1[nTri1].GetP( 1) ;
const Point3d& ptP20 = vTria2[nTri2].GetP( 0) ;
const Point3d& ptP21 = vTria2[nTri2].GetP( 1) ;
// I triangoli sono sono stati flippati
if ( AreSamePointEpsilon( ptP10, ptP21, EPS_ZERO) &&
AreSamePointEpsilon( ptP11, ptP20, EPS_ZERO) &&
! AreSameVectorApprox( vTria1[nTri1].GetN(), vTria2[nTri2].GetN())) {
// Segmento che congiunge le sharp-features
CurveComposite cvLine ;
if ( cvLine.AddPoint( ptP10) && cvLine.AddLine( ptP11))
vLine.emplace_back( cvLine) ;
}
}
}
for ( int n = 0 ; n < nVoxelNum ; ++ n) {
const SharpTriaStruct& SharpTria = m_BlockSharpTria[nBlock][n] ;
// Ciclo sulle componenti connesse del voxel
int nNumCompo = int( SharpTria.ptCompoVert.size()) ;
for ( int nCompo = 0 ; nCompo < nNumCompo ; ++ nCompo) {
const TRIA3DEXVECTOR& vTria = SharpTria.vCompoTria[nCompo] ;
// Numero di triangoli della componente connessa
int nTriNum = int( vTria.size()) ;
for ( int nTri = 0 ; nTri < nTriNum ; ++ nTri) {
// Il triangolo ha un lato sulla sharp-feature
if ( vTria[nTri].GetEdgeFlag( 0)) {
const Point3d& ptPS = vTria[nTri].GetP( 0) ;
const Point3d& ptPE = vTria[nTri].GetP( 1) ;
// Segmento sharp-feature
vBpt.emplace_back( ptPS, ptPE) ;
}
}
}
else if ( vTria[nTri].GetEdgeFlag( 1)) {
const Point3d& ptPS = vTria[nTri].GetP( 1) ;
const Point3d& ptPE = vTria[nTri].GetP( 2) ;
// Segmento sharp-feature
vBpt.emplace_back( ptPS, ptPE) ;
}
else if ( vTria[nTri].GetEdgeFlag( 2)) {
const Point3d& ptPS = vTria[nTri].GetP( 2) ;
const Point3d& ptPE = vTria[nTri].GetP( 0) ;
// Segmento sharp-feature
vBpt.emplace_back( ptPS, ptPE) ;
}
}
}
}
}
// Ciclo sui triangoli feature al confine tra blocchi
for ( int tFB = 0 ; tFB < m_nNumBlock ; ++ tFB) {
int nFBijk[3] ;
GetBlockIJKFromN( int( tFB), nFBijk) ;
for ( int tLB = tFB ; tLB < m_nNumBlock ; ++ tLB) {
int nLBijk[3] ;
GetBlockIJKFromN( int( tLB), nLBijk) ;
// Se i blocchi non sono adiacenti salto l'iterazione
if ( abs( nFBijk[0] - nLBijk[0]) > 1 ||
abs( nFBijk[1] - nLBijk[1]) > 1 ||
abs( nFBijk[2] - nLBijk[2]) > 1)
continue ;
// Numero di voxel nei blocchi correnti
int nVoxelNumFB = int( m_InterBlockSharpTria[tFB].size()) ;
int nVoxelNumLB = int( m_InterBlockSharpTria[tLB].size()) ;
// Ciclo sui voxel dei due blocchi
for ( int tVFB = 0 ; tVFB < nVoxelNumFB ; ++ tVFB) {
for ( int tVLB = 0 ; tVLB < nVoxelNumLB ; ++ tVLB) {
// Se i voxel non sono adiacenti salto l'iterazione
if ( abs( m_InterBlockSharpTria[tFB][tVFB].i - m_InterBlockSharpTria[tLB][tVLB].i) > 1 ||
abs( m_InterBlockSharpTria[tFB][tVFB].j - m_InterBlockSharpTria[tLB][tVLB].j) > 1 ||
abs( m_InterBlockSharpTria[tFB][tVFB].k - m_InterBlockSharpTria[tLB][tVLB].k) > 1)
continue ;
// Numero di componenti connesse dei voxel
int nCompoVFBNum = int( m_InterBlockSharpTria[tFB][tVFB].ptCompoVert.size()) ;
int nCompoVLBNum = int( m_InterBlockSharpTria[tLB][tVLB].ptCompoVert.size()) ;
// Ciclo sulle componenti connesse
for ( int tCmpF = 0 ; tCmpF < nCompoVFBNum ; ++ tCmpF) {
for ( int tCmpL = 0 ; tCmpL < nCompoVLBNum ; ++ tCmpL) {
// Numero di triangoli delle componenti connesse
int nTriFBNum = int( m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF].size()) ;
int nTriLBNum = int( m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL].size()) ;
// Ciclo sui triangoli
for ( int tTriFB = 0 ; tTriFB < nTriFBNum ; ++ tTriFB) {
for ( int tTriLB = 0 ; tTriLB < nTriLBNum ; ++ tTriLB) {
// Punti che devono essere in comune fra i due triangoli
Point3d ptPF0 = m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 0) ;
Point3d ptPF1 = m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 1) ;
Point3d ptPL0 = m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 0) ;
Point3d ptPL1 = m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 1) ;
// I triangoli sono stati flippati
if ( AreSamePointEpsilon( ptPF0, ptPL1, EPS_ZERO) &&
AreSamePointEpsilon( ptPF1, ptPL0, EPS_ZERO) &&
! AreSameVectorApprox( m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetN(),
m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetN())) {
// Segmento che congiunge le sharp-features
CurveComposite cvLine ;
if ( cvLine.AddPoint( ptPF0) && cvLine.AddLine( ptPF1))
vLine.emplace_back( cvLine) ;
}
}
}
}
for ( int tB = 0 ; tB < m_nNumBlock ; ++ tB) {
// Numero di voxel nel blocco corrente
int nVoxelNum = int( m_InterBlockSharpTria[tB].size()) ;
// Ciclo sui voxel del blocco
for ( int tV = 0 ; tV < nVoxelNum ; ++ tV) {
// Numero di componenti connesse del voxel
int nCompoNum = int( m_InterBlockSharpTria[tB][tV].ptCompoVert.size()) ;
// Ciclo sulle componenti connesse
for ( int tC = 0 ; tC < nCompoNum ; ++ tC) {
// Numero di triangoli della componente connessa
int nTriNum = int( m_InterBlockSharpTria[tB][tV].vCompoTria[tC].size()) ;
// Ciclo sui triangoli
for ( int tT = 0 ; tT < nTriNum ; ++ tT) {
// Il triangolo ha un lato sulla sharp-feature
if ( m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetEdgeFlag( 0)) {
const Point3d& ptPS = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 0) ;
const Point3d& ptPE = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 1) ;
// Segmento sharp-feature
vBpt.emplace_back( ptPS, ptPE) ;
}
}
else if ( m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetEdgeFlag( 1)) {
const Point3d& ptPS = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 1) ;
const Point3d& ptPE = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 2) ;
// Segmento sharp-feature
vBpt.emplace_back( ptPS, ptPE) ;
}
else if ( m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetEdgeFlag( 2)) {
const Point3d& ptPS = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 2) ;
const Point3d& ptPE = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 0) ;
// Segmento sharp-feature
vBpt.emplace_back( ptPS, ptPE) ;
}
}
}
}
}
// Creo le curve
for ( int n = 0 ; n < int( vLine.size()) ; ++ n) {
bool bExpanded = false ;
int nNumSt = 0 ;
int nNumEn = 0 ;
int nMSt = - 1 ;
int nMEn = - 1 ;
Point3d ptSt, ptEn ;
vLine[n].GetStartPoint( ptSt) ;
vLine[n].GetEndPoint( ptEn) ;
for ( int m = 0 ; m < int( vLine.size()) ; ++ m) {
if ( m == n)
continue ;
Point3d ptStM, ptEnM ;
vLine[m].GetStartPoint( ptStM) ;
vLine[m].GetEndPoint( ptEnM) ;
if ( AreSamePointEpsilon( ptSt, ptStM, 100 * EPS_SMALL) || AreSamePointEpsilon( ptSt, ptEnM, 100 * EPS_SMALL)) {
nMSt = m ;
++ nNumSt ;
}
if ( AreSamePointEpsilon( ptEn, ptStM, 100 * EPS_SMALL) || AreSamePointEpsilon( ptEn, ptEnM, 100 * EPS_SMALL)) {
nMEn = m ;
++ nNumEn ;
}
// Concateno le curve rispettando le biforcazioni
const double dToler = 20 * EPS_SMALL ;
ChainCurves chainC ;
chainC.Init( true, dToler, int( vBpt.size())) ;
for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) {
Vector3d vtDir = vBpt[i].second - vBpt[i].first ;
vtDir.Normalize() ;
if ( ! chainC.AddCurve( i + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir))
return false ;
}
// recupero i percorsi concatenati
Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ;
INTVECTOR vId ;
while ( chainC.GetChainFromNear( ptNear, true, vId)) {
// creo una curva composita
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo))
return false ;
// recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita
for ( int i = 0 ; i < int( vId.size()) ; ++ i) {
// creo un segmento di retta
int nInd = abs( vId[i]) - 1 ;
bool bInvert = ( vId[i] < 0) ;
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
if ( IsNull( pLine) || ! pLine->Set( vBpt[nInd].first, vBpt[nInd].second))
return false ;
if ( bInvert)
pLine->Invert() ;
// lo accodo alla composita
if ( ! pCrvCompo->AddCurve( Release( pLine), true, 1.1 * dToler) &&
! AreSamePointApprox( ptNear, ( bInvert ? vBpt[nInd].first : vBpt[nInd].second)))
return false ;
// aggiorno il prossimo near
ptNear = ( bInvert ? vBpt[nInd].first : vBpt[nInd].second) ;
}
if ( nNumSt == 1) {
Point3d ptStM ;
vLine[nMSt].GetStartPoint( ptStM) ;
if ( AreSamePointEpsilon( ptSt, ptStM, 100 * EPS_SMALL))
vLine[nMSt].Invert() ;
bool bAdded = vLine[n].AddCurve( vLine[nMSt], false) ;
vLine.erase( vLine.begin() + nMSt) ;
bExpanded = true ;
}
else if ( nNumEn == 1) {
Point3d ptEnM ;
vLine[nMEn].GetEndPoint( ptEnM) ;
if ( AreSamePointEpsilon( ptEn, ptEnM, 100 * EPS_SMALL))
vLine[nMEn].Invert() ;
bool bAdded = vLine[n].AddCurve( vLine[nMEn]) ;
vLine.erase( vLine.begin() + nMEn) ;
bExpanded = true ;
}
if ( bExpanded)
-- n ;
nMSt = - 1 ;
nMEn = - 1 ;
// se lunghezza curva inferiore a 5 volte la tolleranza, la salto
double dCrvLen ;
if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5 * dToler)
continue ;
// unisco segmenti allineati
pCrvCompo->MergeCurves( dToler, ANG_TOL_STD_DEG) ;
// la salvo
vpCurve.emplace_back( Release( pCrvCompo)) ;
}
for ( int n = 0 ; n < int( vLine.size()) ; ++ n) {
PtrOwner<CurveComposite> pCurve( vLine[n].Clone()) ;
if ( IsNull( pCurve))
return false ;
pCurve->MergeCurves( EPS_SMALL, ANG_TOL_STD_DEG) ;
// Inserisco la curva composita nella raccolta da ritornare
vpCurve.emplace_back( Release( pCurve)) ;
}
return true ;
}