diff --git a/ArcCenTgCurvePnt.cpp b/ArcCenTgCurvePnt.cpp index e6fff01..7083783 100644 --- a/ArcCenTgCurvePnt.cpp +++ b/ArcCenTgCurvePnt.cpp @@ -62,7 +62,7 @@ GetArcCenTgCurvePnt( const Point3d& ptCen, const ICurve& cCrv, const Point3d& pt case CRV_ARC : { const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ; return GetArcCenTgArcPnt( ptCen, crvArc, ptNearStart, ptNearEnd, vtN, pPtTg) ; } - case CRV_BEZ : + case CRV_BEZIER : { const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ; return GetArcCenTgBezierPnt( ptCen, crvBezier, ptNearStart, ptNearEnd, vtN, pPtTg) ; } case CRV_COMPO : diff --git a/ArcPntDirTgCurve.cpp b/ArcPntDirTgCurve.cpp index 4a52a19..a0cbddc 100644 --- a/ArcPntDirTgCurve.cpp +++ b/ArcPntDirTgCurve.cpp @@ -61,7 +61,7 @@ GetArcPntDirTgCurve( const Point3d& ptP, const Vector3d& vtDir, const ICurve& cC case CRV_ARC : { const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ; return GetArcPntDirTgArc( ptP, vtDir, crvArc, ptNear, vtN, pPtTg) ; } - case CRV_BEZ : + case CRV_BEZIER : { const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ; return GetArcPntDirTgBezier( ptP, vtDir, crvBezier, ptNear, vtN, pPtTg) ; } case CRV_COMPO : diff --git a/CircleCenTgCurve.cpp b/CircleCenTgCurve.cpp index 4b09c91..3dddf54 100644 --- a/CircleCenTgCurve.cpp +++ b/CircleCenTgCurve.cpp @@ -58,7 +58,7 @@ GetCircleCenTgCurve( const Point3d& ptCen, const Vector3d& vtN, const ICurve& cC case CRV_ARC : { const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ; return GetCircleCenTgArc( ptCen, vtN, crvArc, ptNear, pPtTg) ; } - case CRV_BEZ : + case CRV_BEZIER : { const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ; return GetCircleCenTgBezier( ptCen, vtN, crvBezier, ptNear, pPtTg) ; } case CRV_COMPO : diff --git a/CurveAux.cpp b/CurveAux.cpp index 2be81b8..08cb8d2 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -483,7 +483,7 @@ CurveToArcsPerpExtrCurve( const ICurve* pCrv, double dLinTol, double dAngTolDeg) // se arco in piano non perpendicolare ad estrusione, curva composita o curva di Bezier trasformo if ( ( pCrv->GetType() == CRV_ARC && ! GetBasicCurveArc(pCrv)->IsInPlanePerpExtr()) || pCrv->GetType() == CRV_COMPO || - pCrv->GetType() == CRV_BEZ) { + pCrv->GetType() == CRV_BEZIER) { // creo un poliarco PolyArc PA ; if ( ! pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, PA)) diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 60eeb7d..9e23f8d 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -39,7 +39,7 @@ using namespace std ; static const double MIN_EXT_WEIGHT = 0.25 ; //---------------------------------------------------------------------------- -GEOOBJ_REGISTER( CRV_BEZ, NGE_C_BEZ, CurveBezier) ; +GEOOBJ_REGISTER( CRV_BEZIER, NGE_C_BEZ, CurveBezier) ; //---------------------------------------------------------------------------- CurveBezier::CurveBezier( void) @@ -277,12 +277,12 @@ CurveBezier::CopyFrom( const CurveBezier& cbSrc) return true ; if ( ! Init( cbSrc.m_nDeg, cbSrc.m_bRat)) return false ; - m_VtExtr = cbSrc.m_VtExtr ; - m_dThick = cbSrc.m_dThick ; - m_nTempProp = cbSrc.m_nTempProp ; m_vPtCtrl = cbSrc.m_vPtCtrl ; if ( cbSrc.m_bRat) m_vWeCtrl = cbSrc.m_vWeCtrl ; + m_VtExtr = cbSrc.m_VtExtr ; + m_dThick = cbSrc.m_dThick ; + m_nTempProp = cbSrc.m_nTempProp ; return true ; } @@ -381,7 +381,6 @@ CurveBezier::Load( NgeReader& ngeIn) // se integrale if ( ! bIsRat) { // recupero e setto punti di controllo - string sLine ; Point3d ptP ; for ( int i = 0 ; i <= nDeg ; ++ i) { // leggo la prossima linea ( un punto) @@ -395,7 +394,6 @@ CurveBezier::Load( NgeReader& ngeIn) // altrimenti razionale else { // recupero e setto punti di controllo - string sLine ; Point3d ptP ; double dW ; for ( int i = 0 ; i <= nDeg ; ++ i) { diff --git a/CurveBezier.h b/CurveBezier.h index 3542ea0..e5189cd 100644 --- a/CurveBezier.h +++ b/CurveBezier.h @@ -176,7 +176,6 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; static const int MAXDEG = 11 ; - static const int ST_PTC = 4 ; private : ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto @@ -193,9 +192,9 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW //----------------------------------------------------------------------------- inline CurveBezier* CreateBasicCurveBezier( void) - { return (static_cast( CreateGeoObj( CRV_BEZ))) ; } + { return (static_cast( CreateGeoObj( CRV_BEZIER))) ; } inline CurveBezier* CloneBasicCurveBezier( const IGeoObj* pGObj) - { if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZ) + { if ( pGObj == nullptr || pGObj->GetType() != CRV_BEZIER) return nullptr ; return (static_cast(pGObj->Clone())) ; } inline const CurveBezier* GetBasicCurveBezier( const IGeoObj* pGObj) diff --git a/CurveComposite.cpp b/CurveComposite.cpp index b636e5f..1e2ee94 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -847,7 +847,7 @@ CurveComposite::IsFlat( Plane3d& plPlane, double dToler) const ! shPL.AddUPoint( nCount + 1, ptP)) return false ; break ; - case CRV_BEZ : + case CRV_BEZIER : { const CurveBezier* pBez = GetBasicCurveBezier( pCrv) ; // inserisco tutti i punti di controllo tranne il primo int nLastPC = pBez->GetDegree() ; @@ -2510,7 +2510,7 @@ CurveComposite::ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDe for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++ Iter) { // se arco in piano non perpendicolare ad estrusione o curva di Bezier trasformo if ( ( (*Iter)->GetType() == CRV_ARC && ! AreSameVectorApprox( m_VtExtr, GetBasicCurveArc( *Iter)->GetNormVersor())) || - (*Iter)->GetType() == CRV_BEZ) { + (*Iter)->GetType() == CRV_BEZIER) { // eseguo trasformazione (*Iter)->SetExtrusion( m_VtExtr) ; PtrOwner pNewCrv( CurveToArcsPerpExtrCurve( (*Iter), dLinTol, dAngTolDeg)) ; diff --git a/DistPointCurve.cpp b/DistPointCurve.cpp index 4e25078..11e1c41 100644 --- a/DistPointCurve.cpp +++ b/DistPointCurve.cpp @@ -41,7 +41,7 @@ DistPointCurve::DistPointCurve( const Point3d& ptP, const ICurve& Curve, bool bI case CRV_ARC : ArcCalculate( ptP, Curve) ; break ; - case CRV_BEZ : + case CRV_BEZIER : CrvBezierCalculate( ptP, Curve) ; break ; case CRV_COMPO : diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index bca9249..eb41f30 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 91fe364..3456cb9 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -355,6 +355,7 @@ copy $(TargetPath) \EgtProg\Dll64 + @@ -478,6 +479,7 @@ copy $(TargetPath) \EgtProg\Dll64 + @@ -567,6 +569,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index 4235999..1077060 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -411,6 +411,9 @@ File di origine\GeoCollision + + File di origine\Geo + @@ -986,6 +989,12 @@ File di intestazione + + File di intestazione + + + File di intestazione\Include + diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index 365b69b..70fa858 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -6644,7 +6644,7 @@ GdbExecutor::ExecuteSelect( const string& sCmd2, const STRVECTOR& vsParams) else if ( sFilter == "CA" || sFilter == "CURVEARC") nFilter = CRV_ARC ; else if ( sFilter == "CB" || sFilter == "CURVEBEZIER") - nFilter = CRV_BEZ ; + nFilter = CRV_BEZIER ; else if ( sFilter == "CC" || sFilter == "CURVECOMPO") nFilter = CRV_COMPO ; else if ( sFilter == "STM" || sFilter == "SURFTRIMESH") diff --git a/IntersCurveCurve.cpp b/IntersCurveCurve.cpp index b17e661..57df98d 100644 --- a/IntersCurveCurve.cpp +++ b/IntersCurveCurve.cpp @@ -49,7 +49,7 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB, for ( int i = 0 ; i < 2 ; ++ i) { // se curva è arco da approssimare oppure è curva di Bezier if ( ( m_pCurve[i]->GetType() == CRV_ARC && IsArcToApprox( *m_pCurve[i])) || - m_pCurve[i]->GetType() == CRV_BEZ) { + m_pCurve[i]->GetType() == CRV_BEZIER) { // approssimo con rette PolyLine PL ; if ( ! m_pCurve[i]->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) diff --git a/LinePerpTwoCurves.cpp b/LinePerpTwoCurves.cpp index 98a365d..307947d 100644 --- a/LinePerpTwoCurves.cpp +++ b/LinePerpTwoCurves.cpp @@ -48,7 +48,7 @@ GetLinePerpTwoCurves( const ICurve& cCrv1, const Point3d& ptNear1, case CRV_ARC : { const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ; return GetLinePerpLineArc( crvLine1, ptNear1, crvArc2, ptNear2) ; } - case CRV_BEZ : + case CRV_BEZIER : return nullptr ; case CRV_COMPO : return nullptr ; @@ -68,7 +68,7 @@ GetLinePerpTwoCurves( const ICurve& cCrv1, const Point3d& ptNear1, case CRV_ARC : { const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ; return GetLinePerpTwoArcs( crvArc1, ptNear1, crvArc2, ptNear2) ; } - case CRV_BEZ : + case CRV_BEZIER : return nullptr ; case CRV_COMPO : return nullptr ; @@ -76,7 +76,7 @@ GetLinePerpTwoCurves( const ICurve& cCrv1, const Point3d& ptNear1, return nullptr ; } } break ; - case CRV_BEZ : + case CRV_BEZIER : return nullptr ; case CRV_COMPO : return nullptr ; diff --git a/LinePntPerpCurve.cpp b/LinePntPerpCurve.cpp index 0cca4d2..038e268 100644 --- a/LinePntPerpCurve.cpp +++ b/LinePntPerpCurve.cpp @@ -42,7 +42,7 @@ GetLinePointPerpCurve( const Point3d& ptP, const ICurve& cCrv, const Point3d& pt case CRV_ARC : { const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ; return GetLinePointPerpArc( ptP, crvArc, ptNear) ; } - case CRV_BEZ : + case CRV_BEZIER : { const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ; return GetLinePointPerpBezier( ptP, crvBezier, ptNear) ; } case CRV_COMPO : diff --git a/LinePntTgCurve.cpp b/LinePntTgCurve.cpp index 97cb09c..ae5af07 100644 --- a/LinePntTgCurve.cpp +++ b/LinePntTgCurve.cpp @@ -43,7 +43,7 @@ GetLinePointTgCurve( const Point3d& ptP, const ICurve& cCrv, const Point3d& ptNe case CRV_ARC : { const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ; return GetLinePointTgArc( ptP, crvArc, ptNear) ; } - case CRV_BEZ : + case CRV_BEZIER : { const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ; return GetLinePointTgBezier( ptP, crvBezier, ptNear) ; } case CRV_COMPO : diff --git a/LineTgCurvePerpCurve.cpp b/LineTgCurvePerpCurve.cpp index 7a03ba9..dcbc8dc 100644 --- a/LineTgCurvePerpCurve.cpp +++ b/LineTgCurvePerpCurve.cpp @@ -47,7 +47,7 @@ GetLineTgCurvePerpCurve( const ICurve& cCrv1, const Point3d& ptNear1, { const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ; return GetLineTgLinePerpArc( crvLine1, ptNear1, crvArc2, ptNear2) ; } return nullptr ; - case CRV_BEZ : + case CRV_BEZIER : return nullptr ; case CRV_COMPO : return nullptr ; @@ -65,7 +65,7 @@ GetLineTgCurvePerpCurve( const ICurve& cCrv1, const Point3d& ptNear1, case CRV_ARC : { const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ; return GetLineTgArcPerpArc( crvArc1, ptNear1, crvArc2, ptNear2) ; } - case CRV_BEZ : + case CRV_BEZIER : return nullptr ; case CRV_COMPO : return nullptr ; @@ -73,7 +73,7 @@ GetLineTgCurvePerpCurve( const ICurve& cCrv1, const Point3d& ptNear1, return nullptr ; } } - case CRV_BEZ : + case CRV_BEZIER : return nullptr ; case CRV_COMPO : return nullptr ; diff --git a/LineTgTwoCurves.cpp b/LineTgTwoCurves.cpp index bb690e8..d3437a3 100644 --- a/LineTgTwoCurves.cpp +++ b/LineTgTwoCurves.cpp @@ -46,7 +46,7 @@ GetLineTgTwoCurves( const ICurve& cCrv1, const Point3d& ptNear1, case CRV_ARC : { const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ; return GetLineTgLineArc( crvLine1, ptNear1, crvArc2, ptNear2) ; } - case CRV_BEZ : + case CRV_BEZIER : return nullptr ; case CRV_COMPO : return nullptr ; @@ -66,7 +66,7 @@ GetLineTgTwoCurves( const ICurve& cCrv1, const Point3d& ptNear1, case CRV_ARC : { const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ; return GetLineTgTwoArcs( crvArc1, ptNear1, crvArc2, ptNear2) ; } - case CRV_BEZ : + case CRV_BEZIER : return nullptr ; case CRV_COMPO : return nullptr ; @@ -74,7 +74,7 @@ GetLineTgTwoCurves( const ICurve& cCrv1, const Point3d& ptNear1, return nullptr ; } } - case CRV_BEZ : + case CRV_BEZIER : return nullptr ; case CRV_COMPO : return nullptr ; diff --git a/NgeConst.h b/NgeConst.h index 8d65494..ee496b4 100644 --- a/NgeConst.h +++ b/NgeConst.h @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- -// EgalTech 2014-2019 +// EgalTech 2014-2020 //---------------------------------------------------------------------------- -// File : NgeConst.h Data : 27.12.19 Versione : 2.2a1 +// File : NgeConst.h Data : 22.03.20 Versione : 2.2c3 // Contenuto : Costanti per file Nge. // // @@ -16,6 +16,7 @@ // 04.10.15 DS 1013 -> Aggiunto TextureData. // 18.09.18 DS 1014 -> Aggiunto flag Shape a Zmap. // 27.12.19 DS 1015 -> Aggiunto DIMENSION. +// 22.03.20 DS 1016 -> Aggiunta SurfBezier. // //---------------------------------------------------------------------------- @@ -38,7 +39,8 @@ const int NGE_VER_1012 = 1012 ; // aggiunta superficie FlatRegion const int NGE_VER_1013 = 1013 ; // aggiunto TextureData (Keyword T) const int NGE_VER_1014 = 1014 ; // aggiunto Shape a Zmap const int NGE_VER_1015 = 1015 ; // aggiunto Dimension -const int NGE_VER_LAST = NGE_VER_1015 ; +const int NGE_VER_1016 = 1016 ; // aggiunta superficie Bezier +const int NGE_VER_LAST = NGE_VER_1016 ; // Indici KeyWord const int NGE_START = 0 ; const int NGE_END = 1 ; @@ -60,7 +62,8 @@ const int NGE_C_BEZ = 16 ; const int NGE_C_CMP = 17 ; const int NGE_S_TRM = 18 ; const int NGE_S_FRG = 19 ; -const int NGE_V_ZMP = 20 ; -const int NGE_E_TXT = 21 ; -const int NGE_E_DIM = 22 ; -const int NGE_LAST_ID = 22 ; // ultimo valore +const int NGE_S_BEZ = 20 ; +const int NGE_V_ZMP = 21 ; +const int NGE_E_TXT = 22 ; +const int NGE_E_DIM = 23 ; +const int NGE_LAST_ID = 23 ; // ultimo valore diff --git a/NgeKeyW.h b/NgeKeyW.h index 6b2d999..99f773b 100644 --- a/NgeKeyW.h +++ b/NgeKeyW.h @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- -// EgalTech 2014-2019 +// EgalTech 2014-2020 //---------------------------------------------------------------------------- -// File : NgeKeyW.h Data : 27.12.19 Versione : 2.2a1 +// File : NgeKeyW.h Data : 22.03.20 Versione : 2.2c3 // Contenuto : Parole chiave per file Nge. // // // // Modifiche : 13.04.14 DS Creazione modulo. -// +// 22.03.20 DS Aggiunta "S_BEZ". // //---------------------------------------------------------------------------- @@ -40,6 +40,7 @@ const std::string NgeAscKeyW[] = { "START", // NGE_START "C_CMP", // NGE_C_CMP "S_TRM", // NGE_S_TRM "S_FRG", // NGE_S_FRG + "S_BEZ", // NGE_S_BEZ "V_ZMP", // NGE_V_ZMP "E_TXT", // NGE_E_TXT "E_DIM"} ; // NGE_E_DIM @@ -68,10 +69,11 @@ const int NgeBinKeyW[] = { NGEB_GEN_BASE + 0x0F0F, // NGE_START NGEB_GEO_BASE + GEO_FRAME3D, // NGE_G_FRM NGEB_GEO_BASE + CRV_LINE, // NGE_C_LIN NGEB_GEO_BASE + CRV_ARC, // NGE_C_ARC - NGEB_GEO_BASE + CRV_BEZ, // NGE_C_BEZ + NGEB_GEO_BASE + CRV_BEZIER, // NGE_C_BEZ NGEB_GEO_BASE + CRV_COMPO, // NGE_C_CMP NGEB_GEO_BASE + SRF_TRIMESH, // NGE_S_TRM NGEB_GEO_BASE + SRF_FLATRGN, // NGE_S_FRG + NGEB_GEO_BASE + SRF_BEZIER, // NGE_S_BEZ NGEB_GEO_BASE + VOL_ZMAP, // NGE_V_ZMP NGEB_GEO_BASE + EXT_TEXT, // NGE_E_TXT NGEB_GEO_BASE + EXT_DIMENSION} ; // NGE_E_DIM diff --git a/OutTsc.cpp b/OutTsc.cpp index 977e9b2..3553c90 100644 --- a/OutTsc.cpp +++ b/OutTsc.cpp @@ -537,7 +537,7 @@ OutTsc::PutCurve( const ICurve* pCurve, int nFlag) } // se curva di Bezier e richiesto anche il poligono di controllo - if ( pCurve->GetType() == CRV_BEZ && ( nFlag & 4) != 0) + if ( pCurve->GetType() == CRV_BEZIER && ( nFlag & 4) != 0) PutPolygBez( *(GetCurveBezier( pCurve))) ; // se richiesto il box diff --git a/SelfIntersCurve.cpp b/SelfIntersCurve.cpp index 0ef0b40..9b9f0d7 100644 --- a/SelfIntersCurve.cpp +++ b/SelfIntersCurve.cpp @@ -46,7 +46,7 @@ SelfIntersCurve::SelfIntersCurve( const ICurve& Curve) // se curva è arco da approssimare oppure è curva di Bezier if ( ( m_pCurve->GetType() == CRV_ARC && IsArcToApprox( *m_pCurve)) || - m_pCurve->GetType() == CRV_BEZ) { + m_pCurve->GetType() == CRV_BEZIER) { // approssimo con rette PolyLine PL ; if ( ! m_pCurve->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) diff --git a/SurfBezier.cpp b/SurfBezier.cpp new file mode 100644 index 0000000..27022a3 --- /dev/null +++ b/SurfBezier.cpp @@ -0,0 +1,1028 @@ +//---------------------------------------------------------------------------- +// EgalTech 2020-2020 +//---------------------------------------------------------------------------- +// File : SurfBezier.cpp Data : 22.03.20 Versione : 2.2c3 +// Contenuto : Implementazione della classe Superfici Bezier. +// +// +// +// Modifiche : 22.03.20 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "SurfBezier.h" +#include "GeoObjFactory.h" +#include "NgeWriter.h" +#include "NgeReader.h" +#include "Bernstein.h" +#include "/EgtDev/Include/EGkStringUtils3d.h" +#include "/EgtDev/Include/EGkUiUnits.h" +#include "/EgtDev/Include/EgtNumUtils.h" + +using namespace std ; + +//---------------------------------------------------------------------------- +GEOOBJ_REGISTER( SRF_BEZIER, NGE_S_BEZ, SurfBezier) ; + +//---------------------------------------------------------------------------- +SurfBezier::SurfBezier(void) + : m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_nDegU(), m_nDegV(), m_bRat( false), m_nTempProp( 0) +{ +} + +//---------------------------------------------------------------------------- +SurfBezier::~SurfBezier( void) +{ + m_OGrMgr.Reset() ; + ResetAuxSurf() ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::Init( int nDegU, int nDegV, bool bIsRational) +{ + // verifico validità grado + if ( nDegU < 1 || nDegU > MAXDEG || nDegV < 1 || nDegV > MAXDEG) + return false ; + + // imposto gradi e flag di razionale + m_nDegU = nDegU ; + m_nDegV = nDegV ; + m_bRat = bIsRational ; + + // dimensiono i vettori dei punti e dei pesi + m_vPtCtrl.assign( GetDim(), ORIG) ; + if ( bIsRational) + m_vWeCtrl.assign( GetDim(), 1) ; + else + m_vWeCtrl.clear() ; + m_nStatus = TO_VERIFY ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + return Validate() ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl) +{ + // verifico validità indice + if ( m_nStatus != OK || m_bRat || nInd < 0 || nInd >= GetDim()) + return false ; + + // assegno il valore + m_vPtCtrl[nInd] = ptCtrl ; + + // se razionale, metto il peso a 1 + if ( m_bRat) + m_vWeCtrl[nInd] = 1 ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) +{ + // verifico validità, razionalità e indice + if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd >= GetDim()) + return false ; + + // verifico che il peso non sia nullo o negativo + if ( dW < EPS_SMALL) + return false ; + + // assegno il valore e il peso + m_vPtCtrl[nInd] = ptCtrl ; + m_vWeCtrl[nInd] = dW ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::GetInfo( int& nDegU, int& nDegV, bool& bIsRat) const +{ + // verifico validità superficie + if ( m_nStatus != OK) + return false ; + // restituisco gradi e flag di razionale + nDegU = m_nDegU ; + nDegV = m_nDegV ; + bIsRat = m_bRat ; + return true ; +} + +//---------------------------------------------------------------------------- +const Point3d& +SurfBezier::GetControlPoint( int nInd, bool* pbOk) const +{ + // verifico validità e indice + if ( m_nStatus != OK || nInd < 0 || nInd >= GetDim()) { + if ( pbOk != NULL) + *pbOk = false ; + return ORIG ; + } + // ritorno i dati + if ( pbOk != NULL) + *pbOk = true ; + return m_vPtCtrl[nInd] ; +} + +//---------------------------------------------------------------------------- +double +SurfBezier::GetControlWeight( int nInd, bool* pbOk) const +{ + // verifico validità, razionalità e indice + if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd >= GetDim()) { + if ( pbOk != NULL) + *pbOk = false ; + return 0 ; + } + // ritorno i dati + if ( pbOk != NULL) + *pbOk = true ; + return m_vWeCtrl[nInd] ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::IsAPoint( void) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + // ciclo sui punti + for ( int i = 1 ; i < GetDim() ; ++ i) { + if ( ! AreSamePointApprox( m_vPtCtrl[0], m_vPtCtrl[i])) + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::GetArea( double& dArea) const +{ + // controllo parametro di ritorno + if ( &dArea == nullptr) + return false ; + // inizio con area nulla + dArea = 0 ; + // calcolo l'area + if ( ! GetAuxSurf()) + return false ; + return m_pSTM->GetArea( dArea) ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::GetCentroid( Point3d& ptCen) const +{ + // controllo parametro di ritorno + if ( &ptCen == nullptr) + return false ; + // inizio con centro nell'origine + ptCen = ORIG ; + // calcolo il baricentro + if ( ! GetAuxSurf()) + return false ; + return m_pSTM->GetCentroid( ptCen) ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::GetPointD1D2( double dU, double dV, Point3d& ptPos, + Vector3d* pvtDerU, Vector3d* pvtDerV, Vector3d* pvtDerUU, Vector3d* pvtDerVV, Vector3d* pvtDerUV) const +{ + // la curva deve essere validata + if ( m_nStatus != OK) + return false ; + + // i parametri U e V devono essere compresi tra 0 e 1 + dU = Clamp( dU, 0., 1.) ; + dV = Clamp( dV, 0., 1.) ; + + // se forma polinomiale (o integrale) + if ( ! m_bRat) { + + // calcolo dei polinomi di Bernstein per U di grado opportuno + DBLVECTOR vBernU( m_nDegU + 1) ; + GetAllBernstein( dU, m_nDegU - 2, vBernU) ; + + //// se richiesto, calcolo della derivata seconda + // if ( pvtDer2 != nullptr && pvtDer1 != nullptr) { + // *pvtDer2 = V_NULL ; + // for ( int i = 0 ; i <= m_nDeg - 2 ; ++ i) { + // *pvtDer2 += vBern[i] * ( m_vPtCtrl[i+2] + m_vPtCtrl[i] - 2 * m_vPtCtrl[i+1]) ; + // } + // *pvtDer2 *= m_nDeg * ( m_nDeg - 1) ; + // } + + // aumento il grado + IncreaseAllBernsteinOneDegree( dU, m_nDegU - 1, vBernU) ; + + // se richiesto, calcolo dei vettori intermedi per la derivata prima rispetto ad U + VCT3DVECTOR vtTemp1( m_nDegV + 1, V_NULL) ; + if ( pvtDerU != nullptr) { + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + for ( int i = 0 ; i <= m_nDegU - 1 ; ++ i) + vtTemp1[j] += vBernU[i] * ( m_vPtCtrl[GetInd( i+1, j)] - m_vPtCtrl[GetInd( i, j)]) ; + vtTemp1[j] *= m_nDegU ; + } + } + + // aumento il grado + IncreaseAllBernsteinOneDegree( dU, m_nDegU, vBernU) ; + + // calcolo dei punti intermedi + PNTVECTOR ptTemp( m_nDegV + 1, ORIG) ; + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + for ( int i = 0 ; i <= m_nDegU ; ++ i) + ptTemp[j] += vBernU[i] * m_vPtCtrl[GetInd( i, j)] ; + } + + // calcolo dei polinomi di Bernstein per V di grado opportuno + DBLVECTOR vBernV( m_nDegV + 1) ; + GetAllBernstein( dV, m_nDegV - 1, vBernV) ; + + // se richiesto, calcolo della derivata prima rispetto a V + if ( pvtDerV != nullptr) { + *pvtDerV = V_NULL ; + for ( int j = 0 ; j <= m_nDegV - 1 ; ++ j) + *pvtDerV += vBernV[j] * ( ptTemp[j+1] - ptTemp[j]) ; + *pvtDerV *= m_nDegV ; + } + + // aumento il grado + IncreaseAllBernsteinOneDegree( dV, m_nDegV, vBernV) ; + + // calcolo del punto + ptPos = ORIG ; + for ( int j = 0 ; j <= m_nDegV ; ++ j) + ptPos += vBernV[j] * ptTemp[j] ; + + // se richiesto, calcolo della derivata prima rispetto a U + if ( pvtDerU != nullptr) { + *pvtDerU = V_NULL ; + for ( int j = 0 ; j <= m_nDegV ; ++ j) + *pvtDerU += vBernV[j] * vtTemp1[j] ; + } + } + + // altrimenti forma razionale + else { + + // porto i punti in forma omogenea moltiplicandoli per i pesi + PNTVECTOR vPtWCtrl( GetDim()) ; + for ( int i = 0 ; i < GetDim() ; ++ i) + vPtWCtrl[i] = m_vWeCtrl[i] * m_vPtCtrl[i] ; + + // calcolo dei polinomi di Bernstein di grado opportuno + DBLVECTOR vBernU( m_nDegU + 1) ; + GetAllBernstein( dU, m_nDegU - 2, vBernU) ; + + //// se richiesto, calcolo della derivata seconda + // double dW2 = 0 ; + // if ( pvtDer2 != nullptr && pvtDer1 != nullptr) { + // *pvtDer2 = V_NULL ; + // for ( int i = 0 ; i <= m_nDeg - 2 ; ++ i) { + // *pvtDer2 += vBern[i] * ( vPtWCtrl[i+2] + vPtWCtrl[i] - 2 * vPtWCtrl[i+1]) ; + // dW2 += vBern[i] * ( m_vWeCtrl[i+2] + m_vWeCtrl[i] - 2 * m_vWeCtrl[i+1]) ; + // } + // *pvtDer2 *= m_nDeg * ( m_nDeg - 1) ; + // dW2 *= m_nDeg * ( m_nDeg - 1) ; + // } + + // aumento il grado + IncreaseAllBernsteinOneDegree( dU, m_nDegU - 1, vBernU) ; + + // se richiesto, calcolo dei vettori intermedi per la derivata prima rispetto ad U + VCT3DVECTOR vtTemp1( m_nDegV + 1, V_NULL) ; + DBLVECTOR dTemp1( m_nDegV + 1, 0) ; + if ( pvtDerU != nullptr) { + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + for ( int i = 0 ; i <= m_nDegU - 1 ; ++ i) { + vtTemp1[j] += vBernU[i] * ( vPtWCtrl[GetInd( i+1, j)] - vPtWCtrl[GetInd( i, j)]) ; + dTemp1[j] += vBernU[i] * ( m_vWeCtrl[GetInd( i+1, j)] - m_vWeCtrl[GetInd( i, j)]) ; + } + vtTemp1[j] *= m_nDegU ; + dTemp1[j] *= m_nDegU ; + } + } + + // aumento il grado + IncreaseAllBernsteinOneDegree( dU, m_nDegU, vBernU) ; + + // calcolo dei punti e pesi intermedi + PNTVECTOR ptTempW( m_nDegV + 1, ORIG) ; + DBLVECTOR dTempW( m_nDegV + 1, 0) ; + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + for ( int i = 0 ; i <= m_nDegU ; ++ i) { + ptTempW[j] += vBernU[i] * vPtWCtrl[GetInd( i, j)] ; + dTempW[j] += vBernU[i] * m_vWeCtrl[GetInd( i, j)] ; + } + } + + // calcolo dei polinomi di Bernstein per V di grado opportuno + DBLVECTOR vBernV( m_nDegV + 1) ; + GetAllBernstein( dV, m_nDegV - 1, vBernV) ; + + // se richiesto, calcolo della derivata prima rispetto a V + double dW1v = 0 ; + if ( pvtDerV != nullptr) { + *pvtDerV = V_NULL ; + for ( int j = 0 ; j <= m_nDegV - 1 ; ++ j) { + *pvtDerV += vBernV[j] * ( ptTempW[j+1] - ptTempW[j]) ; + dW1v += vBernV[j] * ( dTempW[j+1] - dTempW[j]) ; + } + *pvtDerV *= m_nDegV ; + dW1v *= m_nDegV ; + } + + // aumento il grado + IncreaseAllBernsteinOneDegree( dV, m_nDegV, vBernV) ; + + // calcolo del punto + double dW = 0 ; + ptPos = ORIG ; + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + ptPos += vBernV[j] * ptTempW[j] ; + dW += vBernV[j] * dTempW[j] ; + } + + // ritrasformo da forma omogenea a forma standard + double dInvW = 1 / ( ( dW > EPS_ZERO) ? dW : EPS_ZERO) ; + ptPos *= dInvW ; + + // se richiesto, calcolo della derivata prima rispetto a U + if ( pvtDerU != nullptr) { + *pvtDerU = V_NULL ; + double dW1u = 0 ; + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + *pvtDerU += vBernV[j] * vtTemp1[j] ; + dW1u += vBernV[j] * dTemp1[j] ; + } + Vector3d vtPos( ptPos.x, ptPos.y, ptPos.z) ; + *pvtDerU = ( *pvtDerU - dW1u * vtPos) * dInvW ; + } + + // se richiesto, completo il calcolo della derivata prima rispetto a V + if ( pvtDerV != nullptr) { + Vector3d vtPos( ptPos.x, ptPos.y, ptPos.z) ; + *pvtDerV = ( *pvtDerV - dW1v * vtPos) * dInvW ; + } + + //if ( pvtDer1 != nullptr) { + // Vector3d vtPos( ptPos.x, ptPos.y, ptPos.z) ; + // *pvtDer1 = ( *pvtDer1 - dW1 * vtPos) * dInvW ; + // if ( pvtDer2 != nullptr) + // *pvtDer2 = ( *pvtDer2 - 2 * dW1 * *pvtDer1 - dW2 * vtPos) * dInvW ; + //} + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::GetPointNrmD1D2( double dU, double dV, Point3d& ptPos, Vector3d& vtN, + Vector3d* pvtDerU, Vector3d* pvtDerV, Vector3d* pvtDerUU, Vector3d* pvtDerVV, Vector3d* pvtDerUV) const +{ + // la curva deve essere validata + if ( m_nStatus != OK) + return false ; + + // i parametri U e V devono essere compresi tra 0 e 1 + dU = Clamp( dU, 0., 1.) ; + dV = Clamp( dV, 0., 1.) ; + + // eseguo calcolo del punto con le derivate prime + Vector3d vtDerU ; + if ( pvtDerU == nullptr) + pvtDerU = &vtDerU ; + Vector3d vtDerV ; + if ( pvtDerV == nullptr) + pvtDerV = &vtDerV ; + GetPointD1D2( dU, dV, ptPos, pvtDerU, pvtDerV) ; + + // calcolo la normale e la verifico + vtN = *pvtDerU ^ *pvtDerV ; + if ( vtN.Normalize()) + return true ; + + // se solo una delle due derivate è piccola, mi sposto lungo il relativo parametro e uso le tangenti + if ( pvtDerU->Len() < EPS_SMALL && pvtDerV->Len() > 10 * EPS_SMALL) { + double dCoeff = ( dU - 1000 * EPS_PARAM < 0. ? 1 : -1) ; + double dUm = dU + 1000 * EPS_PARAM * dCoeff ; + Point3d ptTmp ; + Vector3d vtTmpU, vtTmpV ; + GetPointD1D2( dUm, dV, ptTmp, &vtTmpU, &vtTmpV) ; + vtN = ( *pvtDerV ^ vtTmpV) * dCoeff ; + if ( vtN.Normalize()) + return true ; + } + if ( pvtDerU->Len() > 10 * EPS_SMALL && pvtDerV->Len() < EPS_SMALL) { + double dCoeff = ( dV - 1000 * EPS_PARAM < 0. ? 1 : -1) ; + double dVm = dV + 1000 * EPS_PARAM * dCoeff ; + Point3d ptTmp ; + Vector3d vtTmpU, vtTmpV ; + GetPointD1D2( dU, dVm, ptTmp, &vtTmpU, &vtTmpV) ; + vtN = ( vtTmpU ^ *pvtDerU) * dCoeff ; + if ( vtN.Normalize()) + return true ; + } + + // ricalcolo con una piccola variazione di entrambi i parametri + double dUm ; + if ( dU - 100 * EPS_PARAM < 0.) + dUm = dU + 100 * EPS_PARAM ; + else + dUm = dU - 100 * EPS_PARAM ; + double dVm ; + if ( dV - 100 * EPS_PARAM < 0.) + dVm = dV + 100 * EPS_PARAM ; + else + dVm = dV - 100 * EPS_PARAM ; + Point3d ptTmp ; + GetPointD1D2( dUm, dVm, ptTmp, pvtDerU, pvtDerV) ; + vtN = *pvtDerU ^ *pvtDerV ; + return vtN.Normalize() ; +} + +//---------------------------------------------------------------------------- +SurfBezier* +SurfBezier::Clone( void) const +{ + // alloco oggetto + SurfBezier* pSbz = new( nothrow) SurfBezier ; + if ( pSbz != nullptr) { + if ( ! pSbz->CopyFrom( *this)) { + delete pSbz ; + return nullptr ; + } + } + + return pSbz ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::CopyFrom( const IGeoObj* pGObjSrc) +{ + const SurfBezier* pSbz = dynamic_cast( pGObjSrc) ; + if ( pSbz == nullptr) + return false ; + return CopyFrom( *pSbz) ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::CopyFrom( const SurfBezier& sbSrc) +{ + if ( &sbSrc == this) + return true ; + if ( ! Init( sbSrc.m_nDegU, sbSrc.m_nDegV, sbSrc.m_bRat)) + return false ; + m_nStatus = sbSrc.m_nStatus ; + m_vPtCtrl = sbSrc.m_vPtCtrl ; + if ( sbSrc.m_bRat) + m_vWeCtrl = sbSrc.m_vWeCtrl ; + m_nTempProp = sbSrc.m_nTempProp ; + return true ; +} + +//---------------------------------------------------------------------------- +GeoObjType +SurfBezier::GetType( void) const +{ + return static_cast( GEOOBJ_GETTYPE( SurfBezier)) ; +} + +//---------------------------------------------------------------------------- +const string& +SurfBezier::GetTitle( void) const +{ + static const string sTitle = "SurfBezier" ; + return sTitle ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::Dump( string& sOut, bool bMM, const char* szNewLine) const +{ + // verifico validità superficie + if ( m_nStatus != OK) + sOut += string( "Status=Invalid") + szNewLine ; + // area + double dArea ; + GetArea( dArea) ; + sOut += "Area=" + ToString( GetAreaInUiUnits( dArea, bMM),1) + szNewLine ; + // parametri : flag razionale + sOut += ( m_bRat ? "Rat " : "Int ") ; + // gradi in U e V + sOut += "DegU=" + ToString( m_nDegU) + " DegV=" + ToString( m_nDegV) + szNewLine ; + // ciclo sui punti di controllo ( con pesi se razionale) + for ( int i = 0 ; i < GetDim() ; ++ i) { + sOut += "PC(" + ToString( GetInUiUnits( m_vPtCtrl[i], bMM), 3) ; + if ( m_bRat) + sOut += "," + ToString( m_vWeCtrl[i], 3) ; + sOut += string( ")") + szNewLine ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +int +SurfBezier::GetNgeId( void) const +{ + return GEOOBJ_GETNGEID( SurfBezier) ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::Save( NgeWriter& ngeOut) const +{ + // flag razionale + if ( ! ngeOut.WriteBool( m_bRat, ";")) + return false ; + // gradi + if ( ! ngeOut.WriteInt( m_nDegU, ",") || + ! ngeOut.WriteInt( m_nDegV, ";", true)) + return false ; + // ciclo sui punti di controllo ( con pesi se razionale) + for ( int i = 0 ; i < GetDim() ; ++ i) { + if ( ! m_bRat) { + if ( ! ngeOut.WritePoint( m_vPtCtrl[i], ";", true)) + return false ; + } + else { + if ( ! ngeOut.WritePointW( m_vPtCtrl[i], m_vWeCtrl[i], ";", true)) + return false ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::Load( NgeReader& ngeIn) +{ + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + // leggo la prossima linea ( 3 parametri) + // recupero il flag razionale + bool bIsRat ; + if ( ! ngeIn.ReadBool( bIsRat, ";")) + return false ; + // recupero i gradi + int nDegU, nDegV ; + if ( ! ngeIn.ReadInt( nDegU, ",") || + ! ngeIn.ReadInt( nDegV, ";", true)) + return false ; + // inizializzo la superficie di Bezier + if ( ! Init( nDegU, nDegV, bIsRat)) + return false ; + // se integrale + if ( ! bIsRat) { + // recupero e setto punti di controllo + Point3d ptP ; + for ( int i = 0 ; i < GetDim() ; ++ i) { + // leggo la prossima linea ( un punto) + if ( ! ngeIn.ReadPoint( ptP, ";", true)) + return false ; + // lo assegno + if ( ! SetControlPoint( i, ptP)) + return false ; + } + } + // altrimenti razionale + else { + // recupero e setto punti di controllo + Point3d ptP ; + double dW ; + for ( int i = 0 ; i < GetDim() ; ++ i) { + // leggo la prossima linea ( un punto con peso) + if ( ! ngeIn.ReadPointW( ptP, dW, ";", true)) + return false ; + // lo assegno + if ( ! SetControlPoint( i, ptP, dW)) + return false ; + } + } + + // eseguo validazione + return Validate() ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::Validate( void) +{ + if ( m_nStatus == TO_VERIFY) + m_nStatus = ( ( m_nDegU * m_nDegV > 0 && m_vPtCtrl.size() > 0) ? OK : ERR) ; + + return ( m_nStatus == OK) ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::GetLocalBBox( BBox3d& b3Loc, int nFlag) const +{ + // assegno il box in locale + if ( ! GetAuxSurf()) + return false ; + return m_pSTM->GetLocalBBox( b3Loc, nFlag) ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const +{ + // assegno il box nel riferimento + if ( ! GetAuxSurf()) + return false ; + return m_pSTM->GetBBox( frRef, b3Ref, nFlag) ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::Translate( const Vector3d& vtMove) +{ + // la superficie deve essere validata + if ( m_nStatus != OK) + return false ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + // traslo i punti di controllo + for ( auto& ptP : m_vPtCtrl) + ptP.Translate( vtMove) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) +{ + // la superficie deve essere validata + if ( m_nStatus != OK) + return false ; + + // verifico validità dell'asse di rotazione + if ( vtAx.IsSmall()) + return false ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + // ruoto i punti di controllo + for ( auto& ptP : m_vPtCtrl) + ptP.Rotate( ptAx, vtAx, dCosAng, dSinAng) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) +{ + // la superficie deve essere validata + if ( m_nStatus != OK) + return false ; + + // verifico non sia nulla + if ( abs( dCoeffX) < EPS_ZERO && abs( dCoeffY) < EPS_ZERO && abs( dCoeffZ) < EPS_ZERO) + return false ; + + // calcolo bbox allineato con riferimento di scalatura e senza tener conto dello spessore + // lo scalo per verificare se tutto si riduce a un punto o una linea (solo se diretta come assi ref) + BBox3d b3Ref ; + if ( ! GetBBox( frRef, b3Ref)) + return false ; + Vector3d vtDelta = b3Ref.GetMax() - b3Ref.GetMin() ; + bool bZeroX = ( abs( vtDelta.x * dCoeffX) < EPS_SMALL) ; + bool bZeroY = ( abs( vtDelta.y * dCoeffY) < EPS_SMALL) ; + bool bZeroZ = ( abs( vtDelta.z * dCoeffZ) < EPS_SMALL) ; + if ( ( bZeroX && bZeroY) || ( bZeroX && bZeroZ) || ( bZeroY && bZeroZ)) + return false ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + // scalo i punti di controllo + for ( auto& ptP : m_vPtCtrl) + ptP.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) +{ + // la superficie deve essere validata + if ( m_nStatus != OK) + return false ; + + // verifico validità del piano di specchiatura + if ( vtNorm.IsSmall()) + return false ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + // specchio i punti di controllo + for ( auto& ptP : m_vPtCtrl) + ptP.Mirror( ptOn, vtNorm) ; + + // eseguo invert per mantenere l'orientazione + return Invert() ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) +{ + // la superficie deve essere validata + if ( m_nStatus != OK) + return false ; + + // verifico validità dei parametri + if ( vtNorm.IsSmall() || vtDir.IsSmall()) + return false ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + // eseguo scorrimento dei punti di controllo + for ( auto& ptP : m_vPtCtrl) + ptP.Shear( ptOn, vtNorm, vtDir, dCoeff) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::ToGlob( const Frame3d& frRef) +{ + // la superficie deve essere validata + if ( m_nStatus != OK) + return false ; + + // verifico validità del frame + if ( frRef.GetType() == Frame3d::ERR) + return false ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + // trasformo i punti di controllo + for ( auto& ptP : m_vPtCtrl) + ptP.ToGlob( frRef) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::ToLoc( const Frame3d& frRef) +{ + // la superficie deve essere validata + if ( m_nStatus != OK) + return false ; + + // verifico validità del frame + if ( frRef.GetType() == Frame3d::ERR) + return false ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + // trasformo i punti di controllo + for ( auto& ptP : m_vPtCtrl) + ptP.ToLoc( frRef) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) +{ + // la superficie deve essere validata + if ( m_nStatus != OK) + return false ; + + // verifico validità dei frame + if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR) + return false ; + + // se i due riferimenti coincidono, non devo fare alcunché + if ( AreSameFrame( frOri, frDest)) + return true ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + // trasformo i punti di controllo + for ( auto& ptP : m_vPtCtrl) + ptP.LocToLoc( frOri, frDest) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::Invert( void) +{ + // la superficie deve essere validata + if ( m_nStatus != OK) + return false ; + + // imposto ricalcolo della grafica + ResetAuxSurf() ; + m_OGrMgr.Reset() ; + + // inverto + PNTVECTOR vPtCtrl = m_vPtCtrl ; + int l = 0 ; + for ( int i = 0 ; i <= m_nDegU ; ++ i) { + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + int k = i + ( m_nDegU + 1) * j ; + m_vPtCtrl[l] = vPtCtrl[k] ; + ++ l ; + } + } + if ( m_bRat) { + DBLVECTOR vWeCtrl = m_vWeCtrl ; + int l = 0 ; + for ( int i = 0 ; i <= m_nDegU ; ++ i) { + for ( int j = 0 ; j <= m_nDegV ; ++ j) { + int k = i + ( m_nDegU + 1) * j ; + m_vWeCtrl[l] = vWeCtrl[k] ; + ++ l ; + } + } + } + swap( m_nDegU, m_nDegV) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::GetControlCurveOnU( int nIndV, PolyLine& plCtrlU) const +{ + plCtrlU.Clear() ; + if ( nIndV < 0 || nIndV > m_nDegV) + return false ; + for ( int i = 0 ; i <= m_nDegU ; ++ i) + plCtrlU.AddUPoint( double( i) / m_nDegU, m_vPtCtrl[GetInd( i, nIndV)]) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const +{ + plCtrlV.Clear() ; + if ( nIndU < 0 || nIndU > m_nDegU) + return false ; + for ( int i = 0 ; i <= m_nDegV ; ++ i) + plCtrlV.AddUPoint( double( i) / m_nDegV, m_vPtCtrl[GetInd( nIndU, i)]) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::GetCurveOnU( double dV, PolyLine& plCtrlU) const +{ + plCtrlU.Clear() ; + if ( dV < - EPS_PARAM || dV > 1 + EPS_PARAM) + return false ; + dV = Clamp( dV, 0., 1.) ; + int nStepU = 20 * m_nDegU ; + double dStepU = 1.0 / nStepU ; + for ( int i = 0 ; i <= nStepU ; ++ i) { + double dU = i * dStepU ; + Point3d ptPos ; + if ( GetPointD1D2( dU, dV, ptPos)) + plCtrlU.AddUPoint( dU, ptPos) ; + else + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfBezier::GetCurveOnV( double dU, PolyLine& plCtrlV) const +{ + plCtrlV.Clear() ; + if ( dU < - EPS_PARAM || dU > 1 + EPS_PARAM) + return false ; + dU = Clamp( dU, 0., 1.) ; + int nStepV = 20 * m_nDegV ; + double dStepV = 1.0 / nStepV ; + for ( int j = 0 ; j <= nStepV ; ++ j) { + double dV = j * dStepV ; + Point3d ptPos ; + if ( GetPointD1D2( dU, dV, ptPos)) + plCtrlV.AddUPoint( dV, ptPos) ; + else + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +const ISurfTriMesh* +SurfBezier::GetAuxSurf( void) const +{ + // la superficie deve essere validata + if ( m_nStatus != OK) { + m_pSTM = nullptr ; + return nullptr ; + } + // se già calcolata, la restituisco + if ( m_pSTM != nullptr) + return m_pSTM ; + // la creo + PtrOwner pSTM( CreateBasicSurfTriMesh()) ; + if ( IsNull( pSTM)) + return nullptr ; + // prima isoparametrica + PolyLine PL1 ; + GetCurveOnU( 0, PL1) ; + // ciclo sulle isoparametriche + int nStrip = 20 * m_nDegV ; + for ( int i = 1 ; i <= nStrip ; ++ i) { + // altra isoparametrica + PolyLine PL2 ; + GetCurveOnU( double( i) / nStrip, PL2) ; + // creo la trimesh tra le due isoparametriche + PtrOwner pSt12( CreateBasicSurfTriMesh()) ; + if ( IsNull( pSt12)) + return nullptr ; + if ( PL1.GetPointNbr() == 1) { + Point3d ptP ; PL1.GetFirstPoint( ptP) ; + pSt12->CreateByPointCurve( ptP, PL2) ; + pSt12->Invert() ; + } + else if ( PL2.GetPointNbr() == 1) { + Point3d ptP ; PL2.GetFirstPoint( ptP) ; + pSt12->CreateByPointCurve( ptP, PL1) ; + } + else + pSt12->CreateByTwoCurves( PL1, PL2, ISurfTriMesh::RLT_ISOPAR) ; + // inserisco questa trimesh in quella complessiva + pSTM->DoSewing( *pSt12) ; + // salvo isoparametrica PL2 in PL1 + PL1.GetUPointList().swap( PL2.GetUPointList()) ; + } + // la salvo + m_pSTM = Release( pSTM) ; + return m_pSTM ; +} + +//---------------------------------------------------------------------------- +void +SurfBezier::ResetAuxSurf( void) const +{ + if ( m_pSTM != nullptr) + delete( m_pSTM) ; + m_pSTM = nullptr ; +} diff --git a/SurfBezier.h b/SurfBezier.h new file mode 100644 index 0000000..5e57f6f --- /dev/null +++ b/SurfBezier.h @@ -0,0 +1,156 @@ +//---------------------------------------------------------------------------- +// EgalTech 2020-2020 +//---------------------------------------------------------------------------- +// File : SurfBezier.h Data : 22.03.20 Versione : 2.2c3 +// Contenuto : Dichiarazione della classe Superficie Bezier. +// +// +// +// Modifiche : 22.03.20 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#pragma once + +#include "ObjGraphicsMgr.h" +#include "DllMain.h" +#include "GeoObjRW.h" +#include "SurfTriMesh.h" +#include "/EgtDev/Include/EGkSurfBezier.h" +#include "/EgtDev/Include/EGkGeoCollection.h" + + +//---------------------------------------------------------------------------- +class SurfBezier : public ISurfBezier, public IGeoObjRW +{ + public : // IGeoObj + ~SurfBezier( void) override ; + SurfBezier* Clone( void) const override ; + GeoObjType GetType( void) const override ; + bool IsValid( void) const override + { return ( m_nStatus == OK) ; } + const std::string& GetTitle( void) const override ; + bool Dump( std::string& sOut, bool bMM = true, const char* szNewLine = "\n") const override ; + bool GetLocalBBox( BBox3d& b3Loc, int nFlag = BBF_STANDARD) const override ; + bool GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag = BBF_STANDARD) const override ; + bool Translate( const Vector3d& vtMove) override ; + bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngDeg) override + { double dAngRad = dAngDeg * DEGTORAD ; + return Rotate( ptAx, vtAx, cos( dAngRad), sin( dAngRad)) ; } + bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) override ; + bool Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) override ; + bool Mirror( const Point3d& ptOn, const Vector3d& vtNorm) override ; + bool Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) override ; + bool ToGlob( const Frame3d& frRef) override ; + bool ToLoc( const Frame3d& frRef) override ; + bool LocToLoc( const Frame3d& frOri, const Frame3d& frDest) override ; + void SetObjGraphics( IObjGraphics* pOGr) override + { m_OGrMgr.SetObjGraphics( pOGr) ; } + IObjGraphics* GetObjGraphics( void) override + { return m_OGrMgr.GetObjGraphics() ; } + const IObjGraphics* GetObjGraphics( void) const override + { return m_OGrMgr.GetObjGraphics() ; } + void SetTempProp( int nProp) override + { m_nTempProp = nProp ; } + int GetTempProp( void) const override + { return m_nTempProp ; } + + public : // ISurf + bool IsSimple( void) const override + { return true ; } + bool IsClosed( void) const override + { return false ; } + bool GetArea( double& dArea) const override ; + bool GetVolume( double& dVolume) const override + { if ( &dVolume == nullptr) + return false ; + dVolume = 0 ; + return true ; } + bool GetCentroid( Point3d& ptCen) const override ; + bool Invert( void) override ; + + public : // ISurfBezier + bool CopyFrom( const IGeoObj* pGObjSrc) override ; + bool Init( int nDegU, int nDegV, bool bIsRational) override ; + bool SetControlPoint( int nIndU, int nIndV, const Point3d& ptCtrl) override + { return SetControlPoint( GetInd( nIndU, nIndV), ptCtrl) ; } + bool SetControlPoint( int nInd, const Point3d& ptCtrl) override ; + bool SetControlPoint( int nIndU, int nIndV, const Point3d& ptCtrl, double dW) override + { return SetControlPoint( GetInd( nIndU, nIndV), ptCtrl, dW) ; } + bool SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) override ; + bool GetInfo( int& nDegU, int& nDegV, bool& bIsRat) const override ; + const Point3d& GetControlPoint( int nIndU, int nIndV, bool* pbOk) const override + { return GetControlPoint( GetInd( nIndU, nIndV), pbOk) ; } + const Point3d& GetControlPoint( int nInd, bool* pbOk) const override ; + double GetControlWeight( int nIndU, int nIndV, bool* pbOk) const override + { return GetControlWeight( GetInd( nIndU, nIndV), pbOk) ; } + double GetControlWeight( int nInd, bool* pbOk) const override ; + bool IsAPoint( void) const override ; + bool GetPointD1D2( double dU, double dV, Point3d& ptPos, + Vector3d* pvtDerU = nullptr, Vector3d* pvtDerV = nullptr, + Vector3d* pvtDerUU = nullptr, Vector3d* pvtDerVV = nullptr, Vector3d* pvtDerUV = nullptr) const override ; + bool GetPointNrmD1D2( double dU, double dV, Point3d& ptPos, Vector3d& vtN, + Vector3d* pvtDerU = nullptr, Vector3d* pvtDerV = nullptr, + Vector3d* pvtDerUU = nullptr, Vector3d* pvtDerVV = nullptr, Vector3d* pvtDerUV = nullptr) const override ; + bool GetControlCurveOnU( int nIndV, PolyLine& plCtrlU) const override ; + bool GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const override ; + bool GetCurveOnU( double dV, PolyLine& plCtrlU) const override ; + bool GetCurveOnV( double dU, PolyLine& plCtrlV) const override ; + const ISurfTriMesh* GetAuxSurf( void) const override ; + + public : // IGeoObjRW + int GetNgeId( void) const override ; + bool Save( NgeWriter& ngeOut) const override ; + bool Load( NgeReader& ngeIn) override ; + + public : + SurfBezier( void) ; + SurfBezier( const SurfBezier& sbSrc) + { if ( ! CopyFrom( sbSrc)) + LOG_ERROR( GetEGkLogger(), "SurfBezier : copy constructor error") } + SurfBezier& operator =( const SurfBezier& sbSrc) + { if ( ! CopyFrom( sbSrc)) + LOG_ERROR( GetEGkLogger(), "SurfBezier : copy error") + return *this ; } + + private : + enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; + static const int MAXDEG = 11 ; + + private : + bool CopyFrom( const SurfBezier& sbSrc) ; + bool Validate( void) ; + int GetInd( int nIndU, int nIndV) const + { return ( nIndV * ( m_nDegU + 1) + nIndU) ; } + int GetIndU( int nInd) const + { return ( nInd % ( m_nDegU + 1)) ; } + int GetIndV( int nInd) const + { return ( nInd / ( m_nDegU + 1)) ; } + int GetDim( void) const + { return ( m_nDegU + 1) * ( m_nDegV + 1) ; } + void ResetAuxSurf( void) const ; + + private : + ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto + mutable SurfTriMesh* m_pSTM ; // superficie trimesh ausiliaria + Status m_nStatus ; // stato + int m_nDegU ; // grado in U + int m_nDegV ; // grado in V + bool m_bRat ; // flag di razionale/polinomiale + PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo + DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo + int m_nTempProp ; // proprietà temporanea +} ; + +//----------------------------------------------------------------------------- +inline SurfBezier* CreateBasicSurfBezier( void) + { return ( static_cast( CreateGeoObj( SRF_BEZIER))) ; } +inline SurfBezier* CloneBasicSurfBezier( const IGeoObj* pGObj) + { if ( pGObj == nullptr || pGObj->GetType() != SRF_BEZIER) + return nullptr ; + return ( static_cast( pGObj->Clone())) ; } +inline const SurfBezier* GetBasicSurfBezier( const IGeoObj* pGObj) + { return ( dynamic_cast( pGObj)) ; } +inline SurfBezier* GetBasicSurfBezier( IGeoObj* pGObj) + { return ( dynamic_cast( pGObj)) ; } diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index e34c120..897df53 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -3195,14 +3195,14 @@ SurfTriMesh::Invert( void) if ( m_nStatus != OK) return false ; + // imposto ricalcolo della grafica e di hashgrids3d + m_OGrMgr.Reset() ; + ResetHashGrids3d() ; + // inverto i triangoli for ( int i = 0 ; i < GetTriangleSize() ; ++ i) InvertTriangle( i) ; - // imposto ricalcolo della grafica e di hashgrids3d - m_OGrMgr.Reset() ; - ResetHashGrids3d() ; - return true ; } diff --git a/SurfTriMesh.h b/SurfTriMesh.h index e8e2bb6..9c4d6f5 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -154,7 +154,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW public : // ISurfTriMesh bool CopyFrom( const IGeoObj* pGObjSrc) override ; - bool Init( int nNumVert, int nNumTria, int nNumFacet = 0) ; + bool Init( int nNumVert, int nNumTria, int nNumFacet = 0) override ; void SetLinearTolerance( double dLinTol) override { m_dLinTol = (std::max)( dLinTol, EPS_SMALL) ; } void SetBoundaryAngle( double dBoundaryAngDeg) override @@ -332,12 +332,12 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW //----------------------------------------------------------------------------- inline SurfTriMesh* CreateBasicSurfTriMesh( void) - { return (static_cast( CreateGeoObj( SRF_TRIMESH))) ; } + { return ( static_cast( CreateGeoObj( SRF_TRIMESH))) ; } inline SurfTriMesh* CloneBasicSurfTriMesh( const IGeoObj* pGObj) { if ( pGObj == nullptr || pGObj->GetType() != SRF_TRIMESH) return nullptr ; - return (static_cast(pGObj->Clone())) ; } + return ( static_cast( pGObj->Clone())) ; } inline const SurfTriMesh* GetBasicSurfTriMesh( const IGeoObj* pGObj) - { return (dynamic_cast(pGObj)) ; } + { return ( dynamic_cast( pGObj)) ; } inline SurfTriMesh* GetBasicSurfTriMesh( IGeoObj* pGObj) - { return (dynamic_cast(pGObj)) ; } + { return ( dynamic_cast( pGObj)) ; }