EgtGeomKernel 1.6k1 :

- aggiunto offset di regioni
- migliorato offset di curve
- migliorata creazione di regioni.
This commit is contained in:
Dario Sassi
2015-11-03 21:24:31 +00:00
parent 740392c456
commit ba71993098
11 changed files with 553 additions and 22 deletions
BIN
View File
Binary file not shown.
+3
View File
@@ -321,10 +321,12 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="FontNfe.cpp" />
<ClCompile Include="NgeReader.cpp" />
<ClCompile Include="FontOs.cpp" />
<ClCompile Include="RemoveCurveOverlaps.cpp" />
<ClCompile Include="SelfIntersCurve.cpp" />
<ClCompile Include="SfrCreate.cpp" />
<ClCompile Include="SurfFlatRegion.cpp" />
<ClCompile Include="SurfFlatRegionBooleans.cpp" />
<ClCompile Include="SurfFlatRegionOffset.cpp" />
<ClCompile Include="TextureData.cpp" />
<ClCompile Include="UserObjDefault.cpp" />
<ClCompile Include="UserObjFactory.cpp" />
@@ -472,6 +474,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="NgeReader.h" />
<ClInclude Include="ObjGraphicsMgr.h" />
<ClInclude Include="FontOs.h" />
<ClInclude Include="RemoveCurveOverlaps.h" />
<ClInclude Include="SurfFlatRegion.h" />
<ClInclude Include="TextureData.h" />
<ClInclude Include="UserObjDefault.h" />
+9
View File
@@ -318,6 +318,12 @@
<ClCompile Include="TextureData.cpp">
<Filter>File di origine\Gdb</Filter>
</ClCompile>
<ClCompile Include="SurfFlatRegionOffset.cpp">
<Filter>File di origine\Geo</Filter>
</ClCompile>
<ClCompile Include="RemoveCurveOverlaps.cpp">
<Filter>File di origine\GeoInters</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@@ -719,6 +725,9 @@
<ClInclude Include="TextureData.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="RemoveCurveOverlaps.h">
<Filter>File di intestazione</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="EgtGeomKernel.rc">
+5 -2
View File
@@ -80,6 +80,9 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
Point3d ptS2, ptE2 ;
if ( ! m_Arc2.GetStartPoint( ptS2) || ! m_Arc2.GetEndPoint( ptE2))
return ;
// determino se sono chiusi ( cerchi)
bool bClosed1 = AreSamePointApprox( ptS1, ptE1) ;
bool bClosed2 = AreSamePointApprox( ptS2, ptE2) ;
// calcolo del parametro di inizio dell'arco 2 nel riferimento dell'arco 1
double dUS2 ;
int nPosS2 ;
@@ -157,8 +160,8 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
m_bOverlaps = true ;
m_nNumInters = 1 ;
}
// se il massimo di 2 coincide con il minimo di 1 nel secondo giro e 1 non completo -> un punto estremo
if ( fabs( dTurnU - dU2max) * dU2L < EPS_SMALL && dTurnU < 1 - EPS_PARAM) {
// se il massimo di 2 coincide con il minimo di 1 nel secondo giro e 1 e 2 non completi -> un punto estremo
if ( fabs( dTurnU - dU2max) * dU2L < EPS_SMALL && ! bClosed1 && ! bClosed2) {
m_Info[m_nNumInters].IciA[0].dU = 0 ;
m_Info[m_nNumInters].IciB[0].dU = ( bEqVers ? 1 : 0) ;
m_Info[m_nNumInters].IciA[0].ptI = ptS1 ;
+193 -16
View File
@@ -36,6 +36,8 @@ static bool VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2) ;
static bool VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, double dDist, int nType,
CurveComposite& ccAux) ;
static double GetMinDist( double dCoeff, ICurve* pCrv1, ICurve* pCrv2) ;
static bool IsFillet( ICurve* pCrv, double dDist) ;
static bool ModifyFillet( ICurve* pCrv, double dDist, int nType, CurveComposite& ccAux) ;
//----------------------------------------------------------------------------
@@ -54,16 +56,40 @@ OffsetCurve::~OffsetCurve( void)
bool
OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
{
// verifico che la curva esista e si trovi nel piano XY o in uno ad esso parallelo
// verifico che la curva esista e sia piana
Plane3d plPlane ;
if ( pCrv == nullptr || ! pCrv->IsFlat( plPlane) ||
! ( plPlane.vtN.IsZplus() || plPlane.vtN.IsZminus()))
if ( pCrv == nullptr || ! pCrv->IsFlat( plPlane))
return false ;
// se esiste estrusione, verifico sia perpendicolare al piano della curva
Vector3d vtExtr ;
if ( pCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall()) {
if ( ! AreSameOrOppositeVectorApprox( plPlane.vtN, vtExtr))
return false ;
}
else
vtExtr = plPlane.vtN ;
// creo una copia formata solo da rette e archi che giacciono nel piano XY (VtExtr è Z+)
// determino se necessario cambiare riferimento ( dal vettore estrusione)
bool bNeedRef = ( ! vtExtr.IsZplus()) ;
// creo una copia della curva
CurveComposite ccCopy ;
if ( ! ccCopy.CopyFrom( pCrv) ||
! ccCopy.ArcsBezierCurvesToArcsPerpExtr( 10 * EPS_SMALL, ANG_TOL_STD_DEG))
if ( ! ccCopy.CopyFrom( pCrv))
return false ;
ccCopy.SetExtrusion( vtExtr) ;
// se necessario cambio il riferimento
Frame3d frExtr ;
if ( bNeedRef) {
// calcolo il riferimento OCS con VtExtr come asse Z
if ( ! frExtr.Set( ORIG, vtExtr))
return false ;
// esprimo la curva in questo riferimento
ccCopy.ToLoc( frExtr) ;
}
// verifico che la curva sia fatta solo da rette e archi che giacciono nel piano XY (VtExtr è ora Z+)
if ( ! ccCopy.ArcsBezierCurvesToArcsPerpExtr( 10 * EPS_SMALL, ANG_TOL_STD_DEG))
return false ;
// verifico se curva chiusa e non forzata aperta
@@ -108,7 +134,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
vAngs.push_back( 0) ;
}
// primo passo : estraggo entità dalla copia, loro offset elementare e aggiunta raccordi esterni
// primo passo : estraggo entità dalla copia, loro offset elementare e aggiunta raccordi esterni (sempre fillet)
CurveComposite ccCopy2 ;
if ( ! ccCopy2.CopyFrom( &ccCopy))
return false ;
@@ -119,27 +145,29 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
if ( IsNull( pCrv1))
return false ;
pCrv1->SetTempProp( nInd1) ;
if ( ! pCrv1->SimpleOffset( dDist, nType) &&
GetBasicCurveArc( Get( pCrv1))->MyExtendedOffset( dDist, true, nType))
if ( ! pCrv1->SimpleOffset( dDist, ICurve::OFF_FILLET) &&
GetBasicCurveArc( Get( pCrv1))->MyExtendedOffset( dDist, true, ICurve::OFF_FILLET))
pCrv1->SetTempProp( - nInd1) ;
// curve successive
PtrOwner<ICurve> pCrv2( ccCopy2.RemoveFirstOrLastCurve( false)) ;
while ( ! IsNull( pCrv2)) {
// eseguo semplice offset
pCrv2->SetTempProp( nInd1 + 1) ;
if ( ! pCrv2->SimpleOffset( dDist, nType) &&
GetBasicCurveArc( Get( pCrv2))->MyExtendedOffset( dDist, true, nType))
if ( ! pCrv2->SimpleOffset( dDist, ICurve::OFF_FILLET) &&
GetBasicCurveArc( Get( pCrv2))->MyExtendedOffset( dDist, true, ICurve::OFF_FILLET))
pCrv2->SetTempProp( - (nInd1 + 1)) ;
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
CurveComposite ccTemp ;
bool bOk = VerifyAndAdjustExternalAngle( Get( pCrv1), Get( pCrv2), vAngs[nInd1], dDist, nType, ccTemp) ;
bool bOk = VerifyAndAdjustExternalAngle( Get( pCrv1), Get( pCrv2), vAngs[nInd1], dDist, ICurve::OFF_FILLET, ccTemp) ;
// metto in lista curva precedente
m_CrvLst.push_back( Release( pCrv1)) ;
// se aggiunto qualcosa, lo metto in lista
if ( ccTemp.GetCurveCount() > 0) {
PtrOwner<ICurve> pCrv3( ccTemp.RemoveFirstOrLastCurve( false)) ;
while ( ! IsNull( pCrv3))
while ( ! IsNull( pCrv3)) {
m_CrvLst.push_back( Release( pCrv3)) ;
pCrv3.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
}
}
// aggiorno curva precedente
++ nInd1 ;
@@ -159,12 +187,14 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
ICurve* pCrv2 = m_CrvLst.front() ;
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
CurveComposite ccTemp ;
bool bOk = VerifyAndAdjustExternalAngle( pCrv1, pCrv2, vAngs[nInd1], dDist, nType, ccTemp) ;
bool bOk = VerifyAndAdjustExternalAngle( pCrv1, pCrv2, vAngs[nInd1], dDist, ICurve::OFF_FILLET, ccTemp) ;
// se aggiunto qualcosa, lo metto in lista
if ( ccTemp.GetCurveCount() > 0) {
PtrOwner<ICurve> pCrv3( ccTemp.RemoveFirstOrLastCurve( false)) ;
while ( ! IsNull( pCrv3))
while ( ! IsNull( pCrv3)) {
m_CrvLst.push_back( Release( pCrv3)) ;
pCrv3.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
}
}
}
@@ -368,6 +398,48 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
++ iIter ;
}
// ottavo passo : se con smusso o estensione, sostituisco i fillet con questi
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ; ++ iIter) {
// processo le curve semplici della composita
CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
ICURVEPLIST CrvLst ;
PtrOwner<ICurve> pCrv( pCrvCo->RemoveFirstOrLastCurve( false)) ;
while ( ! IsNull( pCrv)) {
// se fillet lo trasformo in smusso o estensione
if ( IsFillet( Get( pCrv), dDist)) {
CurveComposite ccTemp ;
bool bOk = ModifyFillet( Get( pCrv), dDist, nType, ccTemp) ;
// metto in lista le curve risultanti
if ( ccTemp.GetCurveCount() > 0) {
PtrOwner<ICurve> pCrv2( ccTemp.RemoveFirstOrLastCurve( false)) ;
while ( ! IsNull( pCrv2)) {
CrvLst.push_back( Release( pCrv2)) ;
pCrv2.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
}
}
}
// altrimenti salvo in lista
else
CrvLst.push_back( Release( pCrv)) ;
// passo alla curva successiva
pCrv.Set( pCrvCo->RemoveFirstOrLastCurve( false)) ;
}
// rimetto le curve nella composita
for ( auto pCrv : CrvLst) {
pCrvCo->AddCurve( pCrv) ;
}
// unisco tratti allineati
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
}
}
// riporto il risultato nel riferimento originale
if ( bNeedRef) {
for ( auto pCrv : m_CrvLst)
pCrv->ToGlob( frExtr) ;
}
return true ;
}
@@ -692,4 +764,109 @@ GetMinDist( double dCoeff, ICurve* pCrv1, ICurve* pCrv2)
if ( ! dstPC.GetDist( dMinDist))
return 0 ;
return dMinDist ;
}
}
//----------------------------------------------------------------------------
bool
IsFillet( ICurve* pCrv, double dDist)
{
// deve essere un arco
if ( pCrv->GetType() != CRV_ARC)
return false ;
CurveArc* pArc = GetBasicCurveArc( pCrv) ;
// deve avere raggio uguale alla distanza di offset
if ( fabs( pArc->GetRadius() - fabs( dDist)) > EPS_SMALL)
return false ;
// deve essere CCW se offset a destra e CW se offset a sinistra
return ( pArc->GetAngCenter() * dDist > 0) ;
}
//----------------------------------------------------------------------------
bool
ModifyFillet( ICurve* pCrv, double dDist, int nType, CurveComposite& ccAux)
{
// la curva deve essere un arco
CurveArc* pArc = GetBasicCurveArc( pCrv) ;
if ( pArc == nullptr)
return false ;
// angolo al centro dell'arco
double dAngDeg = pArc->GetAngCenter() ;
// elimino dal tipo le parti estranee all'angolo esterno
nType &= ( ICurve::OFF_FILLET | ICurve::OFF_CHAMFER | ICurve::OFF_EXTEND) ;
// se l'angolo esterno supera il retto, offset extend diventa offset chamfer
if ( nType == ICurve::OFF_EXTEND && fabs( dAngDeg) > ANG_RIGHT + EPS_ANG_SMALL)
nType = ICurve::OFF_CHAMFER ;
// se angolo esterno molto piccolo, semplifico tutto
const double SMALL_EXT_ANG = 1.0 ;
bool bAngSmall = ( fabs( dAngDeg) < SMALL_EXT_ANG) ;
if ( bAngSmall)
nType = ICurve::OFF_EXTEND ;
switch ( nType) {
case ICurve::OFF_CHAMFER :
{
// lunghezza aggiuntiva in tangenza
double dLen = fabs( dDist) * tan( fabs( dAngDeg) / 4 * DEGTORAD) ;
// punti di costruzione smusso
Point3d ptP1, ptP1a, ptP2a, ptP2 ;
if ( ! pArc->GetStartPoint( ptP1) || ! pArc->GetEndPoint( ptP2))
return false ;
Vector3d vtDir1, vtDir2 ;
if ( ! pArc->GetStartDir( vtDir1) || ! pArc->GetEndDir( vtDir2))
return false ;
ptP1a = ptP1 + vtDir1 * dLen ;
ptP2a = ptP2 - vtDir2 * dLen ;
// aggiungo una nuova linea
PtrOwner<CurveLine> pLine1( CreateBasicCurveLine()) ;
if ( IsNull( pLine1) || ! pLine1->Set( ptP1, ptP1a))
return false ;
if ( ! ccAux.AddCurve( Release( pLine1)))
return false ;
// tratto intermedio
PtrOwner<CurveLine> pLine2( CreateBasicCurveLine()) ;
if ( IsNull( pLine2) || ! pLine2->Set( ptP1a, ptP2a))
return false ;
if ( ! ccAux.AddCurve( Release( pLine2)))
return false ;
// aggiungo una nuova linea
PtrOwner<CurveLine> pLine3( CreateBasicCurveLine()) ;
if ( IsNull( pLine3) || ! pLine3->Set( ptP2a, ptP2))
return false ;
if ( ! ccAux.AddCurve( Release( pLine3)))
return false ;
return true ;
}
break ;
case ICurve::OFF_EXTEND :
{
// lunghezza aggiuntiva in tangenza
double dLen = fabs( dDist) * tan( fabs( dAngDeg) / 2 * DEGTORAD) ;
// punti di costruzione estensione
Point3d ptP1, ptPc, ptP2 ;
if ( ! pArc->GetStartPoint( ptP1) || ! pArc->GetEndPoint( ptP2))
return false ;
Vector3d vtDir1, vtDir2 ;
if ( ! pArc->GetStartDir( vtDir1) || ! pArc->GetEndDir( vtDir2))
return false ;
ptPc = ptP1 + vtDir1 * dLen ;
// aggiungo una nuova linea
PtrOwner<CurveLine> pLine1( CreateBasicCurveLine()) ;
if ( IsNull( pLine1) || ! pLine1->Set( ptP1, ptPc))
return false ;
if ( ! ccAux.AddCurve( Release( pLine1)))
return false ;
// aggiungo una nuova linea
PtrOwner<CurveLine> pLine2( CreateBasicCurveLine()) ;
if ( IsNull( pLine2) || ! pLine2->Set( ptPc, ptP2))
return false ;
if ( ! ccAux.AddCurve( Release( pLine2)))
return false ;
return true ;
}
}
return false ;
}
+158
View File
@@ -0,0 +1,158 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : RemoveCurveOverlaps.cpp Data : 02.11.15 Versione : 1.6K1
// Contenuto : Implementazione rimozione sovrapposizioni di curva.
//
//
//
// Modifiche : 02.11.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "GeoConst.h"
#include "CurveComposite.h"
#include "RemoveCurveOverlaps.h"
#include "/EgtDev/Include/EGkIntersCurves.h"
#include "/EgtDev/Include/EGkIntervals.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include <algorithm>
using namespace std ;
//----------------------------------------------------------------------------
bool
RemoveCurveOverlaps( ICurve* pCurve, bool bRemoveSam, bool bRemoveCtr, ICURVEPLIST& CrvLst)
{
// Pulisco lista di ritorno
CrvLst.clear() ;
// Acquisisco la curva
PtrOwner<ICurve> pMyCrv( pCurve) ;
// Verifico validità curva
if ( IsNull( pMyCrv) || ! pMyCrv->IsValid())
return false ;
// Se nulla da rimuovere, non devo fare alcunché
if ( ! bRemoveSam && ! bRemoveCtr) {
CrvLst.push_back( Release( pMyCrv)) ;
return true ;
}
// --- la verifica ed eventuale rimozione va effettuata in un piano perpendicolare al vettore estrusione ---
// verifico il vettore estrusione
Vector3d vtExtr ;
pMyCrv->GetExtrusion( vtExtr) ;
bool bNeedRef = ( ! vtExtr.IsSmall() && ! vtExtr.IsZplus()) ;
// se necessario cambio il riferimento
Frame3d frExtr ;
if ( bNeedRef) {
// calcolo il riferimento OCS con VtExtr come asse Z
if ( ! frExtr.Set( ORIG, vtExtr))
return false ;
// esprimo la curva in questo riferimento
pMyCrv->ToLoc( frExtr) ;
}
// Calcolo le auto intersezioni
SelfIntersCurve sintC( *pMyCrv) ;
// se non ci sono sovrapposizioni, non devo fare alcunché
if ( ! sintC.GetOverlaps()) {
// riporto la curva nel riferimento originale
if ( bNeedRef)
pMyCrv->ToGlob( frExtr) ;
// la inserisco in lista
CrvLst.push_back( Release( pMyCrv)) ;
return true ;
}
// Determino intervallo complessivo della curva
double dStart, dEnd ;
if ( ! pMyCrv->GetDomain( dStart, dEnd))
return false ;
Intervals inOk( EPS_PARAM) ;
inOk.Set( dStart, dEnd) ;
// Tolgo le parti in sovrapposizione da eliminare
IntCrvCrvInfo iccInfo ;
for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i) {
// se sovrapposti
if ( iccInfo.bOverlap) {
// se equiversi e da eliminare, elimino solo uno dei due tratti
if ( iccInfo.bCBOverEq && bRemoveSam) {
inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ;
}
// se altrimenti controversi e da eliminare, elimino entrambi i tratti
else if ( ! iccInfo.bCBOverEq && bRemoveCtr) {
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[1].dU) ;
inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ;
}
}
}
// Copio le parti da conservare
double dParS, dParE ;
bool bFound = inOk.GetFirst( dParS, dParE) ;
while ( bFound) {
ICurve* pCrv = pMyCrv->CopyParamRange( dParS, dParE) ;
if ( pCrv != nullptr) {
if ( pCrv->GetType() == CRV_COMPO)
CrvLst.push_back( pCrv) ;
else {
CurveComposite* pCrvCo = new( std::nothrow) CurveComposite ;
if ( pCrvCo != nullptr) {
pCrvCo->AddCurve( pCrv) ;
CrvLst.push_back( pCrvCo) ;
}
}
}
bFound = inOk.GetNext( dParS, dParE) ;
}
// Concateno i percorsi risultanti (senza cambiare verso)
for ( auto iIter = CrvLst.begin() ; iIter != CrvLst.end() ;) {
CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
// recupero punti iniziale e finale della curva
Point3d ptStart, ptEnd ;
pCrvCo->GetStartPoint( ptStart) ;
pCrvCo->GetEndPoint( ptEnd) ;
// ciclo sulle curve successive per verificare se possibile concatenamento
for ( auto iIter2 = next( iIter) ; iIter2 != CrvLst.end() ;) {
CurveComposite* pCrvCo2 = GetBasicCurveComposite( *iIter2) ;
// recupero punti iniziale e finale della curva
Point3d ptStart2, ptEnd2 ;
pCrvCo2->GetStartPoint( ptStart2) ;
pCrvCo2->GetEndPoint( ptEnd2) ;
// verifiche di concatenamento
if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL)) {
pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL) ;
CrvLst.erase( iIter2) ;
ptEnd = ptEnd2 ;
iIter2 = next( iIter) ;
}
else if ( AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) {
pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL) ;
CrvLst.erase( iIter2) ;
ptStart = ptStart2 ;
iIter2 = next( iIter) ;
}
else
++ iIter2 ;
}
++ iIter ;
}
// riporto la curva nel riferimento originale
if ( bNeedRef) {
for ( auto pCrv : CrvLst)
pCrv->ToGlob( frExtr) ;
}
return true ;
}
+20
View File
@@ -0,0 +1,20 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : RemoveCurveOverlaps.h Data : 02.11.15 Versione : 1.6k1
// Contenuto : Dichiarazione funzione rimozione sovrapposizioni curve.
//
//
//
// Modifiche : 02.11.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "/EgtDev/Include/EGkCurve.h"
//----------------------------------------------------------------------------
bool RemoveCurveOverlaps( ICurve* pCurve, bool bRemoveSam, bool bRemoveCtr, ICURVEPLIST& CrvLst) ;
+53 -1
View File
@@ -18,6 +18,8 @@
#include "NgeWriter.h"
#include "NgeReader.h"
#include "CurveAux.h"
#include "CurveComposite.h"
#include "RemoveCurveOverlaps.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGkUiUnits.h"
@@ -80,6 +82,28 @@ SurfFlatRegion::AddExtLoop( const ICurve& cCrv)
//----------------------------------------------------------------------------
bool
SurfFlatRegion::AddExtLoop( ICurve* pCrv)
{
// rimuovo eventuali sovrapposizioni
ICURVEPLIST CrvLst ;
if ( ! RemoveCurveOverlaps( pCrv, true, true, CrvLst))
return false ;
// aggiungo le singole curve
bool bOk = true ;
for ( auto& pCrv : CrvLst) {
// se curva composita, unisco eventuali tratti allineati
CurveComposite* pCrvCo = GetBasicCurveComposite( pCrv) ;
if ( pCrvCo != nullptr)
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
// aggiungo il loop
if ( ! AddSimpleExtLoop( pCrv))
bOk = false ;
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
{
// acquisisco la curva
PtrOwner<ICurve> pMyCrv( pCrv) ;
@@ -116,7 +140,10 @@ SurfFlatRegion::AddExtLoop( ICurve* pCrv)
// porto la curva nel riferimento intrinseco
if ( ! pMyCrv->ToLoc( m_frF))
return false ;
// verifico non abbia auto-intersezioni che si attraversano
Vector3d vtExtr ;
if ( pMyCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall())
pMyCrv->SetExtrusion( Z_AX) ;
// verifico non abbia auto-intersezioni che si attraversano o si sovrappongano
SelfIntersCurve sInt( *pMyCrv) ;
if ( sInt.GetCrossOrOverlapIntersCount() > 0)
return false ;
@@ -190,6 +217,28 @@ SurfFlatRegion::AddIntLoop( const ICurve& cCrv)
//----------------------------------------------------------------------------
bool
SurfFlatRegion::AddIntLoop( ICurve* pCrv)
{
// rimuovo eventuali sovrapposizioni
ICURVEPLIST CrvLst ;
if ( ! RemoveCurveOverlaps( pCrv, true, true, CrvLst))
return false ;
// aggiungo le singole curve
bool bOk = true ;
for ( auto& pCrv : CrvLst) {
// se curva composita, unisco eventuali tratti allineati
CurveComposite* pCrvCo = GetBasicCurveComposite( pCrv) ;
if ( pCrvCo != nullptr)
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
// aggiungo il loop
if ( ! AddSimpleIntLoop( pCrv))
bOk = false ;
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
{
// acquisisco la curva
PtrOwner<ICurve> pMyCrv( pCrv) ;
@@ -204,6 +253,9 @@ SurfFlatRegion::AddIntLoop( ICurve* pCrv)
// porto la curva nel riferimento intrinseco
if ( ! pMyCrv->ToLoc( m_frF))
return false ;
Vector3d vtExtr ;
if ( pMyCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall())
pMyCrv->SetExtrusion( Z_AX) ;
// verifico sia piana e il piano coincida con quello XY intrinseco
double dArea ;
Plane3d plPlane ;
+3
View File
@@ -78,6 +78,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
virtual bool Add( const ISurfFlatRegion& Other) ;
virtual bool Subtract( const ISurfFlatRegion& Other) ;
virtual bool Intersect( const ISurfFlatRegion& Other) ;
virtual bool Offset( double dDist, int nType) ;
virtual const Vector3d& GetNormVersor( void) const
{ return m_frF.VersZ() ; }
virtual int GetChunkCount( void) const ;
@@ -110,7 +111,9 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
private :
bool CopyFrom( const SurfFlatRegion& clSrc) ;
bool AddSimpleExtLoop( ICurve* pCrv) ;
bool MyAddExtLoop( ICurve* pCrv) ;
bool AddSimpleIntLoop( ICurve* pCrv) ;
bool MyAddIntLoop( ICurve* pCrv) ;
int GetIndFromChunkLoop( int nChunk, int nLoop) const ;
bool GetChunkLoopFromInd( int nInd, int& nChunk, int& nLoop) const ;
+11 -3
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : SurfFlatRegion.cpp Data : 18.08.15 Versione : 1.6h4
// File : SurfFlatRegionBooleans.cpp Data : 18.08.15 Versione : 1.6h4
// Contenuto : Implementazione delle funzioni booleane per SurfFlatRegion.
//
//
@@ -158,7 +158,11 @@ SurfFlatRegion::Subtract( const ISurfFlatRegion& Other)
}
// creo una nuova regione a partire da questi loop
PtrOwner<SurfFlatRegion> pSfr( MyNewSurfFromLoops( vpLoop)) ;
PtrOwner<SurfFlatRegion> pSfr ;
if ( vpLoop.size() == 0)
pSfr.Set( new SurfFlatRegion) ;
else
pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
if ( IsNull( pSfr))
return false ;
@@ -237,7 +241,11 @@ SurfFlatRegion::Intersect( const ISurfFlatRegion& Other)
}
// creo una nuova regione a partire da questi loop
PtrOwner<SurfFlatRegion> pSfr( MyNewSurfFromLoops( vpLoop)) ;
PtrOwner<SurfFlatRegion> pSfr ;
if ( vpLoop.size() == 0)
pSfr.Set( new SurfFlatRegion) ;
else
pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
if ( IsNull( pSfr))
return false ;
+98
View File
@@ -0,0 +1,98 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : SurfFlatRegionOffset.cpp Data : 01.11.15 Versione : 1.6k1
// Contenuto : Implementazione della funzione offset per SurfFlatRegion.
//
//
//
// Modifiche : 01.11.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "SurfFlatRegion.h"
#include "/EgtDev/Include/EgkOffsetCurve.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
bool
SurfFlatRegion::Offset( double dDist, int nType)
{
// recupero il numero dei chunk
int nChunk = GetChunkCount() ;
if ( nChunk == 0)
return false ;
// creo una nuova regione
PtrOwner<SurfFlatRegion> pSfr( new SurfFlatRegion) ;
if ( IsNull( pSfr))
return false ;
// ciclo sui chunk
bool bFirstCurve = true ;
for ( int i = 0 ; i < nChunk ; ++ i) {
// ciclo sui loop di ogni chunk
int nLoop = GetLoopCount( i) ;
for ( int j = 0 ; j < nLoop ; ++ j) {
// recupero il loop
ICurve* pLoop = GetMyLoop( i, j) ;
if ( pLoop == nullptr)
return false ;
// ne eseguo l'offset
OffsetCurve OffsCrv ;
bool bOk = OffsCrv.Make( pLoop, dDist, nType) ;
// recupero le curve di offset
PtrOwner<ICurve> pOffs( OffsCrv.GetCurve()) ;
while ( bOk && ! IsNull( pOffs)) {
// se prima curva esterna in assoluto, è il primo contorno esterno della nuova regione
if ( bFirstCurve && j == 0) {
if ( ! pSfr->AddExtLoop( Release( pOffs)))
return false ;
bFirstCurve = false ;
}
// altrimenti aggiungo o sottraggo la regione della curva alla nuova regione
else if ( ! bFirstCurve) {
// se loop interno, inverto la curva
if ( j != 0)
pOffs->Invert() ;
// creo la regione
PtrOwner<SurfFlatRegion> pSfr2( new SurfFlatRegion) ;
if ( IsNull( pSfr2) || ! pSfr2->AddExtLoop( Release( pOffs)))
return false ;
// se era loop esterno, lo aggiungo alla nuova regione
if ( j == 0) {
if ( ! pSfr->Add( *Get( pSfr2)))
return false ;
}
// altrimenti loop interno, lo sottraggo alla nuova regione
else {
if ( ! pSfr->Subtract( *Get( pSfr2)))
return false ;
}
}
// passo alla successiva
pOffs.Set( OffsCrv.GetCurve()) ;
}
}
}
// pulisco la superficie corrente
for ( auto& pLoop : m_vpLoop)
delete pLoop ;
m_vpLoop.clear() ;
// sposto i dati della nuova superficie in quella corrente
m_vExtInd = pSfr->m_vExtInd ;
m_vpLoop = pSfr->m_vpLoop ;
for ( auto& pLoop : pSfr->m_vpLoop)
pLoop = nullptr ;
m_nStatus = pSfr->m_nStatus ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
return true ;
}