//---------------------------------------------------------------------------- // EgalTech 2014-2015 //---------------------------------------------------------------------------- // File : EXE_GdbCreateSurf.cpp Data : 04.05.15 Versione : 1.6e1 // Contenuto : Funzioni di creazione superfici del DB geometrico per EXE. // // // // Modifiche : 02.11.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "EXE.h" #include "EXE_Macro.h" #include "AuxTools.h" #include "GeoTools.h" #include "/EgtDev/Include/EXeExecutor.h" #include "/EgtDev/Include/EXeConst.h" #include "/EgtDev/Include/EGkDistPointLine.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EGkStmStandard.h" #include "/EgtDev/Include/EGkStmFromCurves.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" #include "/EgtDev/Include/EGkSurfBezier.h" #include "/EgtDev/Include/EGkPolygon3d.h" #include "/EgtDev/Include/EGkVolZmap.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkCurveLocal.h" #include "/EgtDev/Include/EGkSurfLocal.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EGkExtText.h" #include "/EgtDev/Include/EGkSbzStandard.h" #include "/EgtDev/Include/EGkSbzFromCurves.h" using namespace std ; //------------------------------------------------------------------------------- int ExeCreateSurfFrRectangle( int nParentId, const Point3d& ptIni, const Point3d& ptCross, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero il riferimento locale Frame3d frLoc ; bool bOk = pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // porto in locale il punto e calcolo la normale in locale Point3d ptIniL = GetPointLocal( pGeomDB, ptIni, nRefType, frLoc) ; Point3d ptCrossL = GetPointLocal( pGeomDB, ptCross, nRefType, frLoc) ; Point3d ptDirL = GetPointLocal( pGeomDB, ptIni + 100 * X_AX, nRefType, frLoc) ; Vector3d vtZL = GetVectorLocal( pGeomDB, Z_AX, nRefType, frLoc) ; // ne ricavo un riferimento intrinseco Frame3d frEnt ; bOk = bOk && frEnt.Set( ptIniL, ptDirL, ptCrossL) ; if ( ( frEnt.VersZ() * vtZL) < 0) frEnt.PseudoMirror( frEnt.Orig(), frEnt.VersZ()) ; // ricavo le dimensioni della base Point3d ptCrossI = GetToLoc( ptCrossL, frEnt) ; double dWidth = ptCrossI.x ; double dLen = ptCrossI.y ; // creo il rettangolo nel suo riferimento intrinseco PtrOwner pSfr( GetSurfFlatRegionRectangle( abs( dWidth), dLen)) ; bOk = bOk && ! IsNull( pSfr) ; // eventuale traslazione per larghezza negativa if ( bOk && dWidth < 0) pSfr->Translate( Vector3d( dWidth, 0, 0)) ; // porto il rettangolo nel riferimento locale bOk = bOk && pSfr->ToGlob( frEnt) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSfr)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfFrRectangle(" + IdToString( nParentId) + ",{" + ToString( ptIni) + "}," + ToString( ptCross) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfFrRectangle3P( int nParentId, const Point3d& ptIni, const Point3d& ptCross, const Point3d& ptDir, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero il riferimento locale Frame3d frLoc ; bool bOk = pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // porto in locale il punto e calcolo la normale in locale Point3d ptIniL = GetPointLocal( pGeomDB, ptIni, nRefType, frLoc) ; Point3d ptCrossL = GetPointLocal( pGeomDB, ptCross, nRefType, frLoc) ; Point3d ptDirL = GetPointLocal( pGeomDB, ptDir, nRefType, frLoc) ; Vector3d vtZL = GetVectorLocal( pGeomDB, Z_AX, nRefType, frLoc) ; // ne ricavo un riferimento intrinseco Frame3d frEnt ; bOk = bOk && frEnt.Set( ptIniL, ptDirL, ptCrossL) ; if ( ( frEnt.VersZ() * vtZL) < 0) frEnt.PseudoMirror( frEnt.Orig(), frEnt.VersZ()) ; // ricavo le dimensioni della base Point3d ptCrossI = ptCrossL ; ptCrossI.ToLoc( frEnt) ; double dWidth = ptCrossI.x ; double dLen = ptCrossI.y ; // creo il rettangolo nel suo riferimento intrinseco PtrOwner pSfr( GetSurfFlatRegionRectangle( abs( dWidth), dLen)) ; bOk = bOk && ! IsNull( pSfr) ; // eventuale traslazione per larghezza negativa if ( bOk && dWidth < 0) pSfr->Translate( Vector3d( dWidth, 0, 0)) ; // porto il rettangolo nel riferimento locale bOk = bOk && pSfr->ToGlob( frEnt) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSfr)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfFrRectangle3P(" + IdToString( nParentId) + ",{" + ToString( ptIni) + "},{" + ToString( ptCross) + "},{" + ToString( ptDir) + "}," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfFrStadium( int nParentId, const Point3d& ptIni, const Point3d& ptCross, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero il riferimento locale Frame3d frLoc ; bool bOk = pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // porto in locale il punto e calcolo la normale in locale Point3d ptIniL = GetPointLocal( pGeomDB, ptIni, nRefType, frLoc) ; Point3d ptCrossL = GetPointLocal( pGeomDB, ptCross, nRefType, frLoc) ; Point3d ptDirL = GetPointLocal( pGeomDB, ptIni + 100 * X_AX, nRefType, frLoc) ; Vector3d vtZL = GetVectorLocal( pGeomDB, Z_AX, nRefType, frLoc) ; // ne ricavo un riferimento intrinseco Frame3d frEnt ; bOk = bOk && frEnt.Set( ptIniL, ptDirL, ptCrossL) ; if ( ( frEnt.VersZ() * vtZL) < 0) frEnt.PseudoMirror( frEnt.Orig(), frEnt.VersZ()) ; // ricavo le dimensioni della base Point3d ptCrossI = ptCrossL ; ptCrossI.ToLoc( frEnt) ; double dWidth = ptCrossI.x ; double dLen = ptCrossI.y ; // creo lo stadium nel suo riferimento intrinseco PtrOwner pSfr( GetSurfFlatRegionStadium( abs( dWidth), dLen)) ; bOk = bOk && ! IsNull( pSfr) ; // eventuale traslazione per larghezza negativa if ( bOk && dWidth < 0) pSfr->Translate( Vector3d( dWidth, 0, 0)) ; // porto lo stadium nel riferimento locale bOk = bOk && pSfr->ToGlob( frEnt) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSfr)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfFrStadium(" + IdToString( nParentId) + ",{" + ToString( ptIni) + "}," + ToString( ptCross) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfFrDisk( int nParentId, const Point3d& ptOrig, double dRad, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero il riferimento locale Frame3d frLoc ; bool bOk = pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // porto in locale il punto e calcolo la normale in locale Point3d ptOrigL = GetPointLocal( pGeomDB, ptOrig, nRefType, frLoc) ; Vector3d vtNL = GetVectorLocal( pGeomDB, Z_AX, nRefType, frLoc) ; // calcolo riferimento per l'entità Frame3d frEnt ; bOk = bOk && frEnt.Set( ptOrigL, vtNL) ; // creo il disco nel suo riferimento intrinseco PtrOwner pSfr( GetSurfFlatRegionDisk( dRad)) ; bOk = bOk && ! IsNull( pSfr) ; // porto il disco nel riferimento locale bOk = bOk && pSfr->ToGlob( frEnt) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSfr)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfFrDisk(" + IdToString( nParentId) + ",{" + ToString( ptOrig) + "}," + ToString( dRad) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfFrFatCurve( int nParentId, int nCrvId, double dRad, bool bSquaredEnds, bool bSquaredMids, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero il riferimento locale Frame3d frLoc ; bool bOk = pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero riferimento della curva Frame3d frCrv ; if ( ! pGeomDB->GetGlobFrame( nCrvId, frCrv)) return GDB_ID_NULL ; // recupero la curva ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ; if ( pCrv == nullptr) return GDB_ID_NULL ; // ne faccio una copia PtrOwner pCopCrv( pCrv->Clone()) ; if ( IsNull( pCopCrv)) return GDB_ID_NULL ; // eseguo la trasformazione (viene eseguita solo se i riferimenti sono diversi pCopCrv->LocToLoc( frCrv, frLoc) ; // creo la regione PtrOwner pSfr( GetSurfFlatRegionFromFatCurve( Release( pCopCrv), dRad, bSquaredEnds, bSquaredMids, dLinTol)) ; bOk = bOk && ! IsNull( pSfr) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSfr)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfFrFatCurve(" + IdToString( nParentId) + "," + ToString( nCrvId) + "," + ToString( dRad) + "," + ToString( bSquaredEnds) + "," + ToString( bSquaredMids) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- static int MyCreateSurfFlatRegion( int nParentId, const INTVECTOR& vCrvIds, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero il riferimento locale Frame3d frLoc ; if ( ! pGeomDB->GetGroupGlobFrame( nParentId, frLoc)) return GDB_ID_NULL ; // costruisco la regione piana SurfFlatRegionByContours SfrCntr ; // creo le copie locali delle curve for ( size_t i = 0 ; i < vCrvIds.size() ; ++ i) { int nId = (( vCrvIds[i] != GDB_ID_SEL) ? vCrvIds[i] : pGeomDB->GetFirstSelectedObj()) ; while ( nId != GDB_ID_NULL) { // recupero riferimento della curva Frame3d frCrv ; if ( ! pGeomDB->GetGlobFrame( nId, frCrv)) return GDB_ID_NULL ; // recupero la curva ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nId)) ; if ( pCrv == nullptr) return GDB_ID_NULL ; // ne faccio una copia PtrOwner pCopCrv( pCrv->Clone()) ; if ( IsNull( pCopCrv)) return GDB_ID_NULL ; // eseguo la trasformazione (viene eseguita solo se i riferimenti sono diversi pCopCrv->LocToLoc( frCrv, frLoc) ; // la assegno al costruttore della regione SfrCntr.AddCurve( Release( pCopCrv)) ; // passo al successivo nId = (( vCrvIds[i] != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ; } } // recupero le regioni int nFirstId = GDB_ID_NULL ; int nCount = 0 ; ISurfFlatRegion* pSfr = SfrCntr.GetSurf() ; while ( pSfr != nullptr) { // inserisco la superficie nel DB int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSfr) ; if ( nNewId == GDB_ID_NULL) return GDB_ID_NULL ; if ( nFirstId == GDB_ID_NULL) nFirstId = nNewId ; ++ nCount ; // recupero la prossima superficie pSfr = SfrCntr.GetSurf() ; } // restituisco l'identificativo della prima nuova entità if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //------------------------------------------------------------------------------- int ExeCreateSurfFlatRegion( int nParentId, const INTVECTOR& vCrvIds, int* pnCount) { // eseguo int nCount = 0 ; int nFirstId = MyCreateSurfFlatRegion( nParentId, vCrvIds, &nCount) ; if ( pnCount != nullptr) *pnCount = nCount ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfFlatRegion(" + IdToString( nParentId) + ",{" + IdListToString( vCrvIds) + "})" + " -- Id=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nFirstId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmEmpty( int nParentId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // creo la superficie vuota PtrOwner pStm( GetSurfTriMeshEmpty()) ; // inserisco la superficie nel DB int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStm)) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmEmpty(" + IdToString( nParentId) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- static int MyCreateSurfTmPlaneInBBox( int nParentId, const Point3d& ptP, const Vector3d& vtN, const BBox3d& b3Box, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // costruisco il piano nel box Plane3d plPlane ; plPlane.Set( ptP, vtN) ; PtrOwner pStm( GetSurfTriMeshPlaneInBox( plPlane, b3Box, true, false)) ; if ( IsNull( pStm)) return GDB_ID_NULL ; // recupero il riferimento locale del gruppo destinazione Frame3d frLoc ; if ( ! pGeomDB->GetGroupGlobFrame( nParentId, frLoc)) return GDB_ID_NULL ; // se necessario, porto la superficie piano trimmato nel riferimento locale if ( nRefType == RTY_GLOB) pStm->ToLoc( frLoc) ; else if ( nRefType == RTY_GRID) pStm->LocToLoc( pGeomDB->GetGridFrame(), frLoc) ; // inserisco la superficie nel DB int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStm)) ; return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmPlaneInBBox( int nParentId, const Point3d& ptP, const Vector3d& vtN, const BBox3d& b3Box, int nRefType) { // creo il piano int nNewId = MyCreateSurfTmPlaneInBBox( nParentId, ptP, vtN, b3Box, nRefType) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmPlaneInBBox(" + IdToString( nParentId) + ",{" + ToString( ptP) + "},{" + ToString( vtN) + "},{{" + ToString( b3Box.GetMin()) + "},{" + ToString( b3Box.GetMax()) + "}}," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- static Triangle3d MyCreateSidePlaneHull( const PNTVECTOR& vVert, bool bNXp, const BBox3d& b3Box, int nFace) { // determino i vertici della superficie sui bordi della faccia Z+ del BBox Triangle3d Tria ; for ( int i = 0 ; i < int( vVert.size()) ; ++ i) { if ( ( nFace == +2 && abs( vVert[i].y - b3Box.GetMax().y) > 100 * EPS_SMALL) || ( nFace == -2 && abs( vVert[i].y - b3Box.GetMin().y) > 100 * EPS_SMALL) || ( nFace == +3 && abs( vVert[i].z - b3Box.GetMax().z) > 100 * EPS_SMALL) || ( nFace == -3 && abs( vVert[i].z - b3Box.GetMin().z) > 100 * EPS_SMALL)) continue ; if ( ( nFace == +2 && abs( vVert[i].z - b3Box.GetMin().z) < 10 * EPS_SMALL) || ( nFace == -2 && abs( vVert[i].z - b3Box.GetMax().z) < 10 * EPS_SMALL) || ( nFace == +3 && abs( vVert[i].y - b3Box.GetMax().y) < 10 * EPS_SMALL) || ( nFace == -3 && abs( vVert[i].y - b3Box.GetMin().y) < 10 * EPS_SMALL)) { int nI = ( bNXp ? 0 : 1) ; Tria.SetP( nI, vVert[i]) ; Tria.SetAttrib( nI, i) ; Tria.SetGrade( Tria.GetGrade() + 2) ; continue ; } if ( ( nFace == +2 && abs( vVert[i].z - b3Box.GetMax().z) < 10 * EPS_SMALL) || ( nFace == -2 && abs( vVert[i].z - b3Box.GetMin().z) < 10 * EPS_SMALL) || ( nFace == +3 && abs( vVert[i].y - b3Box.GetMin().y) < 10 * EPS_SMALL) || ( nFace == -3 && abs( vVert[i].y - b3Box.GetMax().y) < 10 * EPS_SMALL)) { int nI = ( bNXp ? 1 : 0) ; Tria.SetP( nI, vVert[i]) ; Tria.SetAttrib( nI, i) ; Tria.SetGrade( Tria.GetGrade() + 1) ; continue ; } } Tria.SetAttrib( 2, -1) ; if ( Tria.GetGrade() != 3) return Tria ; // determino il piano passante per questa linea che racchiude tutti i punti for ( int i = 0 ; i < int( vVert.size()) ; ++ i) { if ( i != Tria.GetAttrib( 0) && i != Tria.GetAttrib( 1)) { if ( Tria.GetAttrib( 2) == -1 || ( ( vVert[i] - Tria.GetP( 0)) * Tria.GetN() > EPS_ZERO)) { Tria.SetP( 2, vVert[i]) ; Tria.Validate( true) ; Tria.SetAttrib( 2, i) ; } } } return Tria ; } //---------------------------------------------------------------------------- static bool MyCreateSewPolygon( ISurfTriMesh* pStm, const Polygon3d& Polyg) { // verifico esistenza superficie if ( pStm == nullptr) return false ; // se poligono vuoto, non devo fare alcunché if ( Polyg.GetSideCount() == 0) return true ; // creo la superficie trimesh del poligono PtrOwner pStm2( CreateSurfTriMesh()) ; if ( IsNull( pStm2) || ! pStm2->CreateByFlatContour( Polyg.GetPolyLine())) return false ; // le unisco return pStm->DoSewing( *pStm2) ; } //------------------------------------------------------------------------------- static int MyCreateSurfTmConvexHullInBBox( int nParentId, int nId, const BBox3d& b3Box, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie TriMesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return GDB_ID_NULL ; // recupero il suo riferimento e lo porto in quello indicato Frame3d frStm ; if ( ! pGeomDB->GetGlobFrame( nId, frStm)) return GDB_ID_NULL ; frStm = GetFrameInRef( pGeomDB, frStm, GLOB_FRM, nRefType) ; // ne calcolo la normale media Vector3d vtN ; Triangle3d Tria ; int nT = pStm->GetFirstTriangle( Tria) ; while ( nT != SVT_NULL) { // sommo la normale moltiplicata per l'area del triangolo vtN += Tria.GetArea() * Tria.GetN() ; // passo al triangolo successivo nT = pStm->GetNextTriangle( nT, Tria) ; } if ( ! vtN.Normalize()) return GDB_ID_NULL ; vtN.ToGlob( frStm) ; bool bNXp = ( vtN.x >= 0) ; // recupero i vertici e li porto nel riferimento indicato PNTVECTOR vVert ; for ( int i = 0 ; i < pStm->GetVertexSize() ; ++ i) { Point3d ptP ; if ( pStm->GetVertex( i, ptP)) { ptP.ToGlob( frStm) ; vVert.emplace_back( ptP) ; } } // determino i piani che racchiudono tutta la superficie dalle tracce sulla facce laterali della stessa Triangle3d vTria[4] ; vTria[0] = MyCreateSidePlaneHull( vVert, bNXp, b3Box, +3) ; vTria[1] = MyCreateSidePlaneHull( vVert, bNXp, b3Box, -3) ; vTria[2] = MyCreateSidePlaneHull( vVert, bNXp, b3Box, +2) ; vTria[3] = MyCreateSidePlaneHull( vVert, bNXp, b3Box, -2) ; // invalido i triangoli con normale opposta alla direzione attesa for ( int i = 0 ; i < 4 ; ++ i) { if ( abs( vTria[i].GetN().x) < 0.1 || ( vTria[i].GetN().x > 0) != bNXp) vTria[i].Set( vTria[i].GetP( 0), vTria[i].GetP( 1), vTria[i].GetP( 2)) ; } // cerco uno o due piani validi int nPlane1 = -1 ; int nPlane2 = -1 ; for ( int i = 0 ; i < 4 ; ++ i) { if ( ! vTria[i].IsValid()) continue ; nPlane1 = i ; for ( int j = i + 1 ; j < 4 ; ++ j) { if ( vTria[j].IsValid() && abs( vTria[i].GetN() * vTria[j].GetN()) < 0.94) { nPlane2 = j ; break ; } } break ; } // se nessun piano valido if ( nPlane1 == -1) return GDB_ID_NULL ; // se un solo piano valido if ( nPlane2 == -1) return MyCreateSurfTmPlaneInBBox( nParentId, vTria[nPlane1].GetP( 0), vTria[nPlane1].GetN(), b3Box, nRefType) ; // altrimenti due piani validi Polygon3d Polyg1 ; if ( ! Polyg1.FromPlaneTrimmedWithBox( vTria[nPlane1].GetPlane(), b3Box.GetMin(), b3Box.GetMax(), true, false)) return GDB_ID_NULL ; Polygon3d Polyg2 ; if ( ! Polyg2.FromPlaneTrimmedWithBox( vTria[nPlane2].GetPlane(), b3Box.GetMin(), b3Box.GetMax(), true, false)) return GDB_ID_NULL ; if ( ! Polyg1.Trim( Polyg2, true, true, false) || ! Polyg2.Trim( Polyg1, true, false, false)) return GDB_ID_NULL ; // creo la trimesh dalle due facce PtrOwner pChStm( CreateSurfTriMesh()) ; if ( IsNull( pChStm)) return GDB_ID_NULL ; if ( ! MyCreateSewPolygon( pChStm, Polyg1) || ! MyCreateSewPolygon( pChStm, Polyg2)) return GDB_ID_NULL ; pChStm->DoCompacting() ; // recupero il riferimento locale del gruppo destinazione Frame3d frLoc ; if ( ! pGeomDB->GetGroupGlobFrame( nParentId, frLoc)) return GDB_ID_NULL ; // se necessario, porto la superficie piano trimmato nel riferimento locale if ( nRefType == RTY_GLOB) pChStm->ToLoc( frLoc) ; else if ( nRefType == RTY_GRID) pChStm->LocToLoc( pGeomDB->GetGridFrame(), frLoc) ; // inserisco la superficie nel DB int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pChStm)) ; return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmConvexHullInBBox( int nParentId, int nId, const BBox3d& b3Box, int nRefType) { // creo il piano int nNewId = MyCreateSurfTmConvexHullInBBox( nParentId, nId, b3Box, nRefType) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmConvexHullInBBox(" + IdToString( nParentId) + "," + IdToString( nId) + ",{" + ToString( b3Box.GetMin()) + "},{" + ToString( b3Box.GetMax()) + "}}," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmBBox( int nParentId, const BBox3d& b3Box, bool bRegular, int nRefType) { // bounding box orientato come gli assi del riferimento IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero il riferimento locale Frame3d frLoc ; bool bOk = pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // ricavo i punti standard e le dimensioni Point3d ptIni ; double dWidth = 0, dLen = 0, dHeight = 0 ; bOk = bOk && b3Box.GetMinDim( ptIni, dWidth, dLen, dHeight) ; dWidth = max( dWidth, 10 * EPS_SMALL) ; dLen = max( dLen, 10 * EPS_SMALL) ; dHeight = max( dHeight, 10 * EPS_SMALL) ; Point3d ptCross = ptIni + Vector3d( dWidth, dLen) ; Point3d ptDir = ptIni + Vector3d( dWidth, 0) ; // porto in locale i punti Point3d ptIniL = GetPointLocal( pGeomDB, ptIni, nRefType, frLoc) ; Point3d ptCrossL = GetPointLocal( pGeomDB, ptCross, nRefType, frLoc) ; Point3d ptDirL = GetPointLocal( pGeomDB, ptDir, nRefType, frLoc) ; // ne ricavo un riferimento intrinseco Frame3d frBox ; bOk = bOk && frBox.Set( ptIniL, ptDirL, ptCrossL) ; // creo il box nel suo riferimento intrinseco PtrOwner pSTM( GetSurfTriMeshBox( dWidth, dLen, dHeight, bRegular)) ; bOk = bOk && ! IsNull( pSTM) ; // porto il box nel riferimento locale bOk = bOk && pSTM->ToGlob( frBox) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSTM)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmBBox(" + IdToString( nParentId) + ",{{" + ToString( b3Box.GetMin()) + "},{" + ToString( b3Box.GetMax()) + "}}," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmBox( int nParentId, const Point3d& ptIni, const Point3d& ptCross, const Point3d& ptDir, double dHeight, bool bRegular, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero il riferimento locale Frame3d frLoc ; bool bOk = pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // porto in locale i punti Point3d ptIniL = GetPointLocal( pGeomDB, ptIni, nRefType, frLoc) ; Point3d ptCrossL = GetPointLocal( pGeomDB, ptCross, nRefType, frLoc) ; Point3d ptDirL = GetPointLocal( pGeomDB, ptDir, nRefType, frLoc) ; Vector3d vtZL = GetVectorLocal( pGeomDB, Z_AX, nRefType, frLoc) ; // vettore Cross e Dir non possono formare una angolo superiore o uguale al retto if ( ( ptCrossL - ptIniL) * ( ptDirL - ptIniL) < 0) ptDirL = ptIniL -( ptDirL - ptIniL) ; // ne ricavo un riferimento intrinseco Frame3d frBox ; bOk = bOk && frBox.Set( ptIniL, ptDirL, ptCrossL) ; if ( ( frBox.VersZ() * vtZL) < - EPS_SMALL) frBox.PseudoMirror( frBox.Orig(), frBox.VersZ()) ; // ricavo le dimensioni della base Point3d ptCrossI = ptCrossL ; ptCrossI.ToLoc( frBox) ; double dWidth = ptCrossI.x ; double dLen = ptCrossI.y ; // creo il box nel suo riferimento intrinseco PtrOwner pSTM( GetSurfTriMeshBox( abs( dWidth), dLen, dHeight, bRegular)) ; bOk = bOk && ! IsNull( pSTM) ; // eventuale traslazione per larghezza negativa if ( bOk && dWidth < 0) pSTM->Translate( Vector3d( dWidth, 0, 0)) ; // porto il box nel riferimento locale bOk = bOk && pSTM->ToGlob( frBox) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSTM)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmBox(" + IdToString( nParentId) + ",{" + ToString( ptIni) + "},{" + ToString( ptCross) + "},{" + ToString( ptDir) + "}," + ToString( dHeight) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmPyramid( int nParentId, const Point3d& ptIni, const Point3d& ptCross, const Point3d& ptDir, double dHeight, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; if ( ! pGeomDB->GetGroupGlobFrame( nParentId, frLoc)) return GDB_ID_NULL ; // porto in locale i punti Point3d ptIniL = GetPointLocal( pGeomDB, ptIni, nRefType, frLoc) ; Point3d ptCrossL = GetPointLocal( pGeomDB, ptCross, nRefType, frLoc) ; Point3d ptDirL = GetPointLocal( pGeomDB, ptDir, nRefType, frLoc) ; Vector3d vtZL = GetVectorLocal( pGeomDB, Z_AX, nRefType, frLoc) ; // vettore Cross e Dir non possono formare una angolo superiore o uguale al retto if ( ( ptCrossL - ptIniL) * ( ptDirL - ptIniL) < 0) ptDirL = ptIniL -( ptDirL - ptIniL) ; // ne ricavo un riferimento intrinseco Frame3d frBox ; bOk = bOk && frBox.Set( ptIniL, ptDirL, ptCrossL) ; if ( ( frBox.VersZ() * vtZL) < - EPS_SMALL) frBox.PseudoMirror( frBox.Orig(), frBox.VersZ()) ; // ricavo le dimensioni della base Point3d ptCrossI = ptCrossL ; ptCrossI.ToLoc( frBox) ; double dWidth = ptCrossI.x ; double dLen = ptCrossI.y ; // creo la piramide nel suo riferimento intrinseco PtrOwner pSTM( GetSurfTriMeshPyramid( abs( dWidth), dLen, dHeight)) ; bOk = bOk && ! IsNull( pSTM) ; // traslazione per riferimento BL e anche per eventuale larghezza negativa if ( bOk) pSTM->Translate( Vector3d( dWidth / 2 + min( dWidth, 0.), dLen / 2, 0)) ; // porto la piramide nel riferimento locale bOk = bOk && pSTM->ToGlob( frBox) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSTM)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmPyramid(" + IdToString( nParentId) + ",{" + ToString( ptIni) + "},{" + ToString( ptCross) + "},{" + ToString( ptDir) + "}," + ToString( dHeight) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmCylinder( int nParentId, const Point3d& ptOrig, const Vector3d& vtN, double dRad, double dHeight, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // porto in locale il punto e il versore Point3d ptOrigL = GetPointLocal( pGeomDB, ptOrig, nRefType, frLoc) ; Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frLoc) ; // calcolo riferimento OCS a partire da questo punto e versore Frame3d frCyl ; bOk = bOk && frCyl.Set( ptOrigL, vtNL) ; // creo il cilindro nel suo riferimento intrinseco PtrOwner pSTM( GetSurfTriMeshCylinder( dRad, dHeight, dLinTol)) ; bOk = bOk && ! IsNull( pSTM) ; // porto il cilindro nel riferimento locale bOk = bOk && pSTM->ToGlob( frCyl) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSTM)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmCylinder(" + IdToString( nParentId) + ",{" + ToString( ptOrig) + "},{" + ToString( vtN) + "}," + ToString( dRad) + "," + ToString( dHeight) + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmCone( int nParentId, const Point3d& ptOrig, const Vector3d& vtN, double dRad, double dHeight, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // porto in locale il punto e il versore Point3d ptOrigL = GetPointLocal( pGeomDB, ptOrig, nRefType, frLoc) ; Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frLoc) ; // calcolo riferimento OCS a partire da questo punto e versore Frame3d frCyl ; bOk = bOk && frCyl.Set( ptOrigL, vtNL) ; // creo il cono nel suo riferimento intrinseco PtrOwner pSTM( GetSurfTriMeshCone( dRad, dHeight, dLinTol)) ; bOk = bOk && ! IsNull( pSTM) ; // porto il cono nel riferimento locale bOk = bOk && pSTM->ToGlob( frCyl) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSTM)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmCone(" + IdToString( nParentId) + ",{" + ToString( ptOrig) + "},{" + ToString( vtN) + "}," + ToString( dRad) + "," + ToString( dHeight) + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmSphere( int nParentId, const Point3d& ptOrig, double dRad, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // porto in locale il punto Point3d ptOrigL = GetPointLocal( pGeomDB, ptOrig, nRefType, frLoc) ; // creo la sfera PtrOwner pSTM( GetSurfTriMeshSphere( dRad, dLinTol)) ; bOk = bOk && ! IsNull( pSTM) ; // porto la sfera nella sua origine bOk = bOk && pSTM->Translate( ptOrigL - ORIG) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSTM)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmSphere(" + IdToString( nParentId) + ",{" + ToString( ptOrig) + "}," + ToString( dRad) + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmPyramidFrustum( int nParentId, double dBaseDimX, double dBaseDimY, double dTopDimX, double dTopDimY, double dHeight) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // creo il tronco di cono PtrOwner pSTM( GetSurfTriMeshPyramidFrustum( dBaseDimX, dBaseDimY, dTopDimX, dTopDimY, dHeight)) ; bOk = bOk && ! IsNull( pSTM) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSTM)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmPyramidFrustum(" + IdToString( nParentId) + "," + ToString( dBaseDimX) + "," + ToString( dBaseDimY) + "," + ToString( dTopDimX) + "," + ToString( dTopDimY) + "," + ToString( dHeight) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmConeFrustum( int nParentId, double dBaseRad, double dTopRad, double dHeight, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // creo il tronco di cono PtrOwner pSTM( GetSurfTriMeshConeFrustum( dBaseRad, dTopRad, dHeight, dLinTol)) ; bOk = bOk && ! IsNull( pSTM) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSTM)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmConeFrustum(" + IdToString( nParentId) + "," + ToString( dBaseRad) + "," + ToString( dTopRad) + "," + ToString( dHeight) + "," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmTriangle( int nParentId, const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptP3, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero il riferimento locale Frame3d frLoc ; bool bOk = pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // porto in locale i punti Point3d ptP1L = GetPointLocal( pGeomDB, ptP1, nRefType, frLoc) ; Point3d ptP2L = GetPointLocal( pGeomDB, ptP2, nRefType, frLoc) ; Point3d ptP3L = GetPointLocal( pGeomDB, ptP3, nRefType, frLoc) ; // creo la superficie trimesh PtrOwner pStm( CreateSurfTriMesh()) ; bOk = bOk && ! IsNull( pStm) ; // assegno il triangolo if ( bOk) { pStm->Init( 3, 1, 1) ; int vV[3]{ pStm->AddVertex( ptP1L), pStm->AddVertex( ptP2L), pStm->AddVertex( ptP3L)} ; bOk = ( pStm->AddTriangle( vV) != SVT_NULL) && pStm->AdjustTopology() ; } // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStm)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmTriangle(" + IdToString( nParentId) + ",{" + ToString( ptP1) + "},{" + ToString( ptP2) + "},{" + ToString( ptP3) + "}," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmRectangle( int nParentId, const Point3d& ptO, const Point3d& ptL, const Point3d& ptT, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero il riferimento locale Frame3d frLoc ; bool bOk = pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // porto in locale i punti Point3d ptOL = GetPointLocal( pGeomDB, ptO, nRefType, frLoc) ; Point3d ptLL = GetPointLocal( pGeomDB, ptL, nRefType, frLoc) ; Point3d ptTL = GetPointLocal( pGeomDB, ptT, nRefType, frLoc) ; // modifico il punto trasversale per metterlo perpendicolare al lato Lungo ptTL -= ParallCompo( ptTL - ptOL, ptLL - ptOL) ; // calcolo il quarto punto Point3d ptVL = ptTL + ( ptLL - ptOL) ; // creo la superficie trimesh PtrOwner pStm( CreateSurfTriMesh()) ; bOk = bOk && ! IsNull( pStm) ; // assegno il triangolo if ( bOk) { pStm->Init( 4, 2, 1) ; int vV[4]{ pStm->AddVertex( ptOL), pStm->AddVertex( ptLL), pStm->AddVertex( ptTL), pStm->AddVertex( ptVL)} ; int vV1[3]{ vV[0], vV[1], vV[2] } ; int vV2[3]{ vV[2], vV[1], vV[3] } ; bOk = ( pStm->AddTriangle( vV1) != SVT_NULL) && ( pStm->AddTriangle( vV2) != SVT_NULL) && pStm->AdjustTopology() ; } // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStm)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmRectangle(" + IdToString( nParentId) + ",{" + ToString( ptO) + "},{" + ToString( ptL) + "},{" + ToString( ptT) + "}," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmByPolygon( int nParentId, const PolyLine& PL, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento del gruppo destinazione Frame3d frDest ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frDest) ; // creo la superficie trimesh PtrOwner pSTM( CreateSurfTriMesh()) ; bOk = bOk && ! IsNull( pSTM) ; bOk = bOk && pSTM->CreateByFlatContour( PL) ; // eventuale trasformazione per riferimento di espressione dei punti if ( bOk && nRefType == RTY_GLOB) pSTM->ToLoc( frDest) ; else if ( bOk && nRefType == RTY_GRID) pSTM->LocToLoc( pGeomDB->GetGridFrame(), frDest) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSTM)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sPnt ; Point3d ptP ; if ( PL.GetFirstPoint( ptP)) sPnt += "{" + ToString( ptP) + "}" ; while ( PL.GetNextPoint( ptP)) sPnt += ",{" + ToString( ptP) + "}" ; string sLua = "EgtSurfTmByPolygon(" + IdToString( nParentId) + ",{" + sPnt + "}," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmByPolygonWithHoles( int nParentId, const POLYLINEVECTOR& vPL, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento del gruppo destinazione Frame3d frDest ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frDest) ; // creo la superficie trimesh PtrOwner pSTM( CreateSurfTriMesh()) ; bOk = bOk && ! IsNull( pSTM) ; bOk = bOk && pSTM->CreateByPolygonWithHoles( vPL) ; // eventuale trasformazione per riferimento di espressione dei punti if ( bOk && nRefType == RTY_GLOB) pSTM->ToLoc( frDest) ; else if ( bOk && nRefType == RTY_GRID) pSTM->LocToLoc( pGeomDB->GetGridFrame(), frDest) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSTM)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sPnt ; for ( int i = 0 ; i < int( vPL.size()) ; ++ i) { if ( i > 0) sPnt += ",{0/0,0/0,0/0}," ; ; Point3d ptP ; if ( vPL[i].GetFirstPoint( ptP)) sPnt += "{" + ToString( ptP) + "}" ; while ( vPL[i].GetNextPoint( ptP)) sPnt += ",{" + ToString( ptP) + "}" ; } string sLua = "EgtSurfTmByPolygonWithHoles(" + IdToString( nParentId) + ",{" + sPnt + "}," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmByFlatContour( int nParentId, int nCrvId, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero la curva in locale CurveLocal CrvLoc( pGeomDB, nCrvId, frLoc) ; bOk = bOk && ( CrvLoc.Get() != nullptr) ; // calcolo la superficie ISurfTriMesh* pSTM = ( bOk ? GetSurfTriMeshByFlatContour( CrvLoc, dLinTol) : nullptr) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmByFlatContour(" + IdToString( nParentId) + "," + ToString( nCrvId) + "," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmByRegion( int nParentId, const INTVECTOR& vCrvIds, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero le curve in locale CURVELOCALVECTOR vCrvLoc ; vCrvLoc.reserve( vCrvIds.size()) ; CICURVEPVECTOR vCrvP ; vCrvP.reserve( vCrvIds.size()) ; for ( size_t i = 0 ; i < vCrvIds.size() ; ++ i) { int nId = (( vCrvIds[i] != GDB_ID_SEL) ? vCrvIds[i] : pGeomDB->GetFirstSelectedObj()) ; while ( nId != GDB_ID_NULL) { vCrvLoc.emplace_back( pGeomDB, nId, frLoc) ; vCrvP.push_back( vCrvLoc.back().Get()) ; bOk = bOk && ( vCrvLoc[i].Get() != nullptr) ; // passo al successivo nId = (( vCrvIds[i] != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ; } } // calcolo la superficie ISurfTriMesh* pSTM = ( bOk ? GetSurfTriMeshByRegion( vCrvP, dLinTol) : nullptr) ; bOk = bOk && ( pSTM != nullptr) ; // elimino punti ripetuti bOk = bOk && pSTM->DoCompacting() ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmByRegion(" + IdToString( nParentId) + ",{" + IdListToString( vCrvIds) + "}," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmByExtrusion( int nParentId, const INTVECTOR& vCrvIds, const Vector3d& vtExtr, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero le curve in locale CURVELOCALVECTOR vCrvLoc ; vCrvLoc.reserve( vCrvIds.size()) ; ICURVEPVECTOR vCrvP ; vCrvP.reserve( vCrvIds.size()) ; for ( size_t i = 0 ; i < vCrvIds.size() ; ++ i) { int nId = (( vCrvIds[i] != GDB_ID_SEL) ? vCrvIds[i] : pGeomDB->GetFirstSelectedObj()) ; while ( nId != GDB_ID_NULL) { vCrvLoc.emplace_back( pGeomDB, nId, frLoc) ; vCrvP.push_back( const_cast( vCrvLoc.back().Get())) ; bOk = bOk && ( vCrvLoc[i].Get() != nullptr) ; // passo al successivo nId = (( vCrvIds[i] != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ; } } // porto in locale il vettore estrusione Vector3d vtExtrL = GetVectorLocal( pGeomDB, vtExtr, nRefType, frLoc) ; // creo le superfici e le inserisco nel DB int nFirstId = GDB_ID_NULL ; for ( int i = 0 ; i < int( vCrvP.size()) ; ++ i) { // calcolo la superficie ISurfTriMesh* pSTM = ( bOk ? GetSurfTriMeshByExtrusion( vCrvP[i], vtExtrL, false, dLinTol) : nullptr) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; bOk = bOk && ( nNewId != GDB_ID_NULL) ; if ( bOk && nFirstId == GDB_ID_NULL) nFirstId = nNewId ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmByExtrusion(" + IdToString( nParentId) + ",{" + IdListToString( vCrvIds) + "},{" + ToString( vtExtr) + "}," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nFirstId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nFirstId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmByRegionExtrusion( int nParentId, const INTVECTOR& vCrvIds, const Vector3d& vtExtr, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero le curve in locale CURVELOCALVECTOR vCrvLoc ; vCrvLoc.reserve( vCrvIds.size()) ; CICURVEPVECTOR vCrvP ; vCrvP.reserve( vCrvIds.size()) ; for ( size_t i = 0 ; i < vCrvIds.size() ; ++ i) { vCrvLoc.emplace_back( pGeomDB, vCrvIds[i], frLoc) ; vCrvP.push_back( vCrvLoc[i].Get()) ; bOk = bOk && ( vCrvLoc[i].Get() != nullptr) ; } // porto in locale il vettore estrusione Vector3d vtExtrL = GetVectorLocal( pGeomDB, vtExtr, nRefType, frLoc) ; int nNewId = GDB_ID_NULL ; // creo la superficie ISurfTriMesh* pSTM = ( bOk ? GetSurfTriMeshByRegionExtrusion( vCrvP, vtExtrL, dLinTol) : nullptr) ; // inserisco la superficie nel DB nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmByRegionExtrusion(" + IdToString( nParentId) + ",{" + IdListToString( vCrvIds) + "},{" + ToString( vtExtr) + "}," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmByRevolve( int nParentId, int nCrvId, const Point3d& ptAx, const Vector3d& vtAx, bool bCapEnds, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero la curva in locale CurveLocal CrvLoc( pGeomDB, nCrvId, frLoc) ; bOk = bOk && ( CrvLoc.Get() != nullptr) ; // porto in locale punto e vettore asse Point3d ptAxL = GetPointLocal( pGeomDB, ptAx, nRefType, frLoc) ; Vector3d vtAxL = GetVectorLocal( pGeomDB, vtAx, nRefType, frLoc) ; // calcolo la superficie ISurfTriMesh* pSTM = ( bOk ? GetSurfTriMeshByRevolve( CrvLoc, ptAxL, vtAxL, bCapEnds, dLinTol) : nullptr) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmByRevolve(" + IdToString( nParentId) + "," + ToString( nCrvId) + ",{" + ToString( ptAx) + "},{" + ToString( vtAx) + "}," + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBzByPointCurve( int nParentId, int nCrvId, const Point3d& ptTop, bool bCapEnds, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero la curva in locale CurveLocal CrvLoc( pGeomDB, nCrvId, frLoc) ; bOk = bOk && ( CrvLoc.Get() != nullptr) ; // porto in locale punto e vettore asse Point3d ptTopL = GetPointLocal( pGeomDB, ptTop, nRefType, frLoc) ; // calcolo la superficie ISurfBezier* pSTM = ( bOk ? GetSurfBezierRuled( ptTopL, CrvLoc, dLinTol) : nullptr) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBzByPointCurve(" + IdToString( nParentId) + "," + ToString( nCrvId) + ",{" + ToString( ptTop) + "},{" + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmByScrewing( int nParentId, int nCrvId, const Point3d& ptAx, const Vector3d& vtAx, double dAngRotDeg, double dMove, bool bCapEnds, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero la curva in locale CurveLocal CrvLoc( pGeomDB, nCrvId, frLoc) ; bOk = bOk && ( CrvLoc.Get() != nullptr) ; // porto in locale punto e vettore asse Point3d ptAxL = GetPointLocal( pGeomDB, ptAx, nRefType, frLoc) ; Vector3d vtAxL = GetVectorLocal( pGeomDB, vtAx, nRefType, frLoc) ; // calcolo la superficie ISurfTriMesh* pSTM = ( bOk ? GetSurfTriMeshByScrewing( CrvLoc, ptAxL, vtAxL, dAngRotDeg, dMove, bCapEnds, dLinTol) : nullptr) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmByScrewing(" + IdToString( nParentId) + "," + ToString( nCrvId) + ",{" + ToString( ptAx) + "},{" + ToString( vtAx) + "}," + ToString( dAngRotDeg) + "," + ToString( dMove) + "," + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmRectSwept( int nParentId, double dDimH, double dDimV, double dBevelH, double dBevelV, int nGuideId, int nCapType, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero la guida in locale CurveLocal CrvGuide( pGeomDB, nGuideId, frLoc) ; bOk = bOk && ( CrvGuide.Get() != nullptr) ; // creo la superficie trimesh ISurfTriMesh* pSTM = nullptr ; pSTM = ( bOk ? GetSurfTriMeshRectSwept( dDimH, dDimV, dBevelH, dBevelV, CrvGuide, nCapType, dLinTol) : nullptr) ; // inserisco la superficie trimesh nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmRectSwept(" + IdToString( nParentId) + "," + ToString( dDimH) + "," + ToString( dDimV) + "," + ToString( dBevelH) + "," + ToString( dBevelV) + "," + ToString( nGuideId) + "," + ToString( nCapType) + "," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmSwept( int nParentId, int nSectId, int nGuideId, const Vector3d& vtAx, bool bCapEnds, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero la guida in locale CurveLocal CrvGuide( pGeomDB, nGuideId, frLoc) ; bOk = bOk && ( CrvGuide.Get() != nullptr) ; // porto in locale vettore asse Vector3d vtAxL = GetVectorLocal( pGeomDB, vtAx, nRefType, frLoc) ; // inizializzazione superficie e suo Id ISurfTriMesh* pSTM = nullptr ; int nNewId = GDB_ID_NULL ; // recupero il tipo di entità della sezione int nSecType = pGeomDB->GetGeoType( nSectId) ; // controllo se la sezione è definita da una curva if ( ( nSecType & GEO_CURVE) != 0) { // recupero la sezione in locale CurveLocal CrvSect( pGeomDB, nSectId, frLoc) ; bOk = bOk && ( CrvSect.Get() != nullptr) ; // calcolo la Swept pSTM = ( bOk ? GetSurfTriMeshSwept( CrvSect, CrvGuide, vtAxL, bCapEnds, dLinTol) : nullptr) ; // inserisco la superficie trimesh nel DB nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; } // controllo se la sezione è definita da una regione piana else if ( nSecType == SRF_FLATRGN) { // recupero la regione sezione in locale SurfLocal SrfSect( pGeomDB, nSectId, frLoc) ; const ISurfFlatRegion* pSFrSect = GetSurfFlatRegion( SrfSect.Get()) ; bOk = bOk && ( pSFrSect != nullptr) ; // calcolo la Swept pSTM = ( bOk ? GetSurfTriMeshSwept( pSFrSect, CrvGuide, vtAxL, bCapEnds, dLinTol) : nullptr) ; // inserisco la superficie trimesh nel DB nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmSwept(" + IdToString( nParentId) + "," + ToString( nSectId) + "," + ToString( nGuideId) + ",{" + ToString( vtAx) + "}," + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmTransSwept( int nParentId, int nSectId, int nGuideId, bool bCapEnds, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero la sezione in locale CurveLocal CrvSect( pGeomDB, nSectId, frLoc) ; bOk = bOk && ( CrvSect.Get() != nullptr) ; // recupero la guida in locale CurveLocal CrvGuide( pGeomDB, nGuideId, frLoc) ; bOk = bOk && ( CrvGuide.Get() != nullptr) ; // creo la superficie trimesh ISurfTriMesh* pSTM = nullptr ; pSTM = ( bOk ? GetSurfTriMeshTransSwept( CrvSect, CrvGuide, bCapEnds, dLinTol) : nullptr) ; // inserisco la superficie trimesh nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmTransSwept(" + IdToString( nParentId) + "," + ToString( nSectId) + "," + ToString( nGuideId) + "," + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfTmRuled( int nParentId, int nPtOrCrvId1, int nPtOrCrvId2, int nType, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // creo la superficie trimesh ISurfTriMesh* pSTM = nullptr ; // se la prima entità è un punto e la seconda una curva if ( pGeomDB->GetGeoType( nPtOrCrvId1) == GEO_PNT3D && ( pGeomDB->GetGeoType( nPtOrCrvId2) & GEO_CURVE) != 0) { // recupero il punto in locale // recupero riferimento del punto Frame3d frPnt ; bOk = bOk && pGeomDB->GetGlobFrame( nPtOrCrvId1, frPnt) ; // porto il punto in locale Point3d ptP = GetGeoPoint3d( pGeomDB->GetGeoObj( nPtOrCrvId1))->GetPoint() ; bOk = bOk && ptP.LocToLoc( frPnt, frLoc) ; // recupero la curva in locale CurveLocal CrvLoc( pGeomDB, nPtOrCrvId2, frLoc) ; bOk = bOk && ( CrvLoc.Get() != nullptr) ; // calcolo la superficie pSTM = ( bOk ? GetSurfTriMeshRuled( ptP, CrvLoc, dLinTol) : nullptr) ; } // se la prima entità è una curva e la seconda un punto else if ( ( pGeomDB->GetGeoType( nPtOrCrvId1) & GEO_CURVE) != 0 && pGeomDB->GetGeoType( nPtOrCrvId2) == GEO_PNT3D) { // recupero la curva in locale CurveLocal CrvLoc( pGeomDB, nPtOrCrvId1, frLoc) ; bOk = bOk && ( CrvLoc.Get() != nullptr) ; // recupero il punto in locale // recupero riferimento del punto Frame3d frPnt ; bOk = bOk && pGeomDB->GetGlobFrame( nPtOrCrvId2, frPnt) ; // porto il punto in locale Point3d ptP = GetGeoPoint3d( pGeomDB->GetGeoObj( nPtOrCrvId2))->GetPoint() ; bOk = bOk && ptP.LocToLoc( frPnt, frLoc) ; // calcolo la superficie pSTM = ( bOk ? GetSurfTriMeshRuled( ptP, CrvLoc, dLinTol) : nullptr) ; } // se entrambe curve else if ( ( pGeomDB->GetGeoType( nPtOrCrvId1) & GEO_CURVE) != 0 && ( pGeomDB->GetGeoType( nPtOrCrvId2) & GEO_CURVE) != 0) { // recupero la prima curva in locale CurveLocal CrvLoc1( pGeomDB, nPtOrCrvId1, frLoc) ; bOk = bOk && ( CrvLoc1.Get() != nullptr) ; // recupero la seconda curva in locale CurveLocal CrvLoc2( pGeomDB, nPtOrCrvId2, frLoc) ; bOk = bOk && ( CrvLoc2.Get() != nullptr) ; // calcolo la superficie pSTM = ( bOk ? GetSurfTriMeshRuled( CrvLoc1, CrvLoc2, nType, dLinTol) : nullptr) ; } // altrimenti errore else bOk = false ; // inserisco la superficie trimesh nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSTM) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sType = "'IP'" ; if ( nType == ISurfTriMesh::RLT_MINDIST) sType = "'MD'" ; else if ( nType == ISurfTriMesh::RLT_ISOPAR_SMOOTH) sType = "'IP_SM'" ; string sLua = "EgtSurfTmRuled(" + IdToString( nParentId) + "," + ToString( nPtOrCrvId1) + "," + ToString( nPtOrCrvId2) + "," + sType + "," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //---------------------------------------------------------------------------- int ExeCreateSurfTmByTriangles( int nParentId, const INTVECTOR& vIds, bool bErase) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // almeno un oggetto nell'elenco bool bOk = ( vIds.size() > 0) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // Costruttore di trimesh da insieme disordinato di triangoli StmFromTriangleSoup StmFts ; bOk = bOk && StmFts.Start() ; // Recupero tutti i triangoli delle superfici sorgenti e li inserisco nella nuova INTVECTOR vMyIds ; for ( size_t i = 0 ; bOk && i < vIds.size() ; ++ i) { int nId = (( vIds[i] != GDB_ID_SEL) ? vIds[i] : pGeomDB->GetFirstSelectedObj()) ; while ( nId != GDB_ID_NULL) { // salvo Id nel mio elenco vMyIds.emplace_back( nId) ; // recupero la superficie sorgente const ISurfTriMesh* pStmS = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pStmS != nullptr) ; // recupero il riferimento della superficie sorgente Frame3d frSou ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frSou) ; // recupero tutti i triangoli Triangle3d Tria ; int nT = ( bOk ? pStmS->GetFirstTriangle( Tria) : SVT_NULL) ; while ( nT != SVT_NULL) { // aggiusto per i sistemi di riferimento Tria.LocToLoc( frSou, frLoc) ; // inserisco il triangolo nella nuova superficie bOk = bOk && StmFts.AddTriangle( Tria) ; // passo al triangolo successivo nT = pStmS->GetNextTriangle( nT, Tria) ; } // passo al successivo nId = (( vIds[i] != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ; } } // valido la superficie e calcolo le adiacenze bOk = bOk && StmFts.End() ; // chiudo eventuali fessure tra i triangoli PtrOwner pStm( StmFts.GetSurf()) ; bOk = bOk && pStm->Repair() ; // inserisco la superficie trimesh nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStm)) : GDB_ID_NULL) ; // se richiesto, cancello le superfici originali if ( nNewId != GDB_ID_NULL && bErase) { // cancello le superfici originali e determino Id minimo int nMinId = INT_MAX ; for ( auto nId : vMyIds) { pGeomDB->Erase( nId) ; if ( nId < nMinId) nMinId = nId ; } // assegno alla superficie composita l'Id minimo appena trovato if ( pGeomDB->ChangeId( nNewId, nMinId)) nNewId = nMinId ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmByTriangles(" + IdToString( nParentId) + ",{" + IdListToString( vIds) + "}," + ( bErase ? "true" : "false") + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return nNewId ; } //---------------------------------------------------------------------------- int ExeCreateSurfTmBySewing( int nParentId, const INTVECTOR& vIds, bool bErase) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // almeno un oggetto nell'elenco bool bOk = ( vIds.size() > 0) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // puntatore alla nuova superficie PtrOwner pStm( CreateSurfTriMesh()) ; bOk = bOk && ! IsNull( pStm) ; // esecuzione bool bFirst = true ; INTVECTOR vMyIds ; for ( size_t i = 0 ; bOk && i < vIds.size() ; ++ i) { int nId = (( vIds[i] != GDB_ID_SEL) ? vIds[i] : pGeomDB->GetFirstSelectedObj()) ; while ( nId != GDB_ID_NULL) { // salvo Id nel mio elenco vMyIds.emplace_back( nId) ; // recupero la superficie da cucire const ISurfTriMesh* pStmS = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; bOk = bOk && ( pStmS != nullptr) ; // recupero il riferimento Frame3d frStmS ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frStmS) ; // lo esprimo rispetto a quello della prima superficie frStmS.ToLoc( frLoc) ; // se è la prima, copio if ( bFirst) { bOk = bOk && pStm->CopyFrom( pStmS) ; bOk = bOk && pStm->ToGlob( frStmS) ; bFirst = false ; } // altrimenti eseguo la cucitura else bOk = bOk && pStm->DoSewing( *pStmS, frStmS) ; // passo alla successiva nId = (( vIds[i] != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ; } } // compatto bOk = bOk && pStm->DoCompacting() ; // chiudo eventuali fessure tra i triangoli bOk = bOk && pStm->Repair() ; // inserisco la superficie trimesh nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStm)) : GDB_ID_NULL) ; // se richiesto, cancello le superfici originali if ( nNewId != GDB_ID_NULL && bErase) { // cancello le superfici originali e determino Id minimo int nMinId = INT_MAX ; for ( auto nId : vMyIds) { pGeomDB->Erase( nId) ; if ( nId < nMinId) nMinId = nId ; } // assegno alla superficie composita l'Id minimo appena trovato if ( pGeomDB->ChangeId( nNewId, nMinId)) nNewId = nMinId ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmBySewing(" + IdToString( nParentId) + ",{" + IdListToString( vIds) + "}," + ( bErase ? "true" : "false") + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return nNewId ; } //---------------------------------------------------------------------------- int ExeCreateSurfTmByVolZmap( int nParentId, int nZmapId, int nPart) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero il solido VolZmap const IVolZmap* pVZM = GetVolZmap( pGeomDB->GetGeoObj( nZmapId)) ; bool bOk = ( pVZM != nullptr) ; // se richiesta superficie di una sola parte PtrOwner pPart ; if ( bOk && nPart >= 0) { pPart.Set( pVZM->ClonePart( nPart)) ; bOk = ! IsNull( pPart) ; pVZM = pPart ; } // recupero il riferimento del solido sorgente Frame3d frSou ; bOk = bOk && pGeomDB->GetGlobFrame( nZmapId, frSou) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // Recupero la TriMesh PtrOwner pStm ; bOk = bOk && pStm.Set( pVZM->GetSurfTriMesh()) ; bOk = bOk && ( ! IsNull( pStm)) ; // la porto in locale al frame di destinazione bOk = bOk && pStm->LocToLoc( frSou, frLoc) ; // inserisco la superficie trimesh nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStm)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmByVolZmap(" + IdToString( nParentId) + "," + IdToString( nZmapId) + "," + IdToString( nPart) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return nNewId ; } //---------------------------------------------------------------------------- static double GetStmOffsPrec( double dOffs, double dLinTol) { return max( min( abs( dOffs) / 4., 10. * max( dLinTol, EPS_SMALL)), 0.5) ; } //------------------------------------------------------------------------------- int ExeCreateSurfShell( int nParentId, int nSurfId, double dThick, double dLinTol) { // Verifica del DB geometrico IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // Sistemo lo spessore ( diretto in direzione opposta alla normale della superficie) e ala tolleranza lineare bool bOk = ( abs( dThick) > 10. * EPS_SMALL) ; double dOffs = ( - abs( dThick)) ; double dMyLinTol = max( EPS_SMALL, dLinTol) ; // Recupero la superficie const ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( nSurfId)) ; bOk = bOk && ( pSurf != nullptr && pSurf->IsValid()) ; // Recupero il riferimento del gruppo di destinazione Frame3d frDest ; bOk = bOk && ( pGeomDB->GetGroupGlobFrame( nParentId, frDest)) ; // Definisco la TriMesh risultate PtrOwner pStmRes( CreateSurfTriMesh()) ; bOk = bOk && ( ! IsNull( pStmRes)) ; // Definisco la Shell in base al tipo di superficie if ( bOk) { switch ( pSurf->GetType()) { case SRF_TRIMESH : { // Recupero la superficie TriMesh ( deve essere aperta) const ISurfTriMesh* pStm = GetSurfTriMesh( pSurf) ; bOk = ( pStm != nullptr && pStm->IsValid() && ! pStm->IsClosed()) ; if ( bOk) { double dPrec = GetStmOffsPrec( dOffs, dMyLinTol) ; bOk = ( pStmRes.Set( CreateSurfTriMeshShell( pStm, dOffs, dPrec))) ; bOk = bOk && ( ! IsNull( pStmRes) && pStmRes->IsValid()) ; } } break ; case SRF_BEZIER : { // Recupero la superficie di Bezier const ISurfBezier* pSBz = GetSurfBezier( pSurf) ; bOk = ( pSBz != nullptr && pSBz->IsValid()) ; // TODO : bOk = false ; // <--- } break ; case SRF_FLATRGN : { // Recupero la superficie piana const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pSurf) ; bOk = ( pSfr != nullptr && pSfr->IsValid()) ; // Definisco la superficie di estrusione dai Loops della regione piana CICURVEPVECTOR vLoops ; for ( int nChunk = 0 ; bOk && nChunk < pSfr->GetChunkCount() ; ++ nChunk) { for ( int nLoop = 0 ; bOk && nLoop < pSfr->GetLoopCount( nChunk) ; ++ nLoop) bOk = ( vLoops.emplace_back( pSfr->GetLoop( nChunk, nLoop)) && vLoops.back()->IsValid()) ; } bOk = bOk && pStmRes.Set( GetSurfTriMeshByRegionExtrusion( vLoops, - dOffs * pSfr->GetNormVersor(), dMyLinTol)) ; } default : bOk = false ; break ; } } // Verifico che la superficie risultante sia valida bOk = bOk && ( ! IsNull( pStmRes) && pStmRes->IsValid()) ; // Porto la superficie risultante nel frame di destinazione bOk = bOk && ( pStmRes->ToLoc( frDest)) ; // Inserisco la superficie trimesh nel DB int nNewId = GDB_ID_NULL ; if ( bOk) { nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStmRes)) ; bOk = ( nNewId != GDB_ID_NULL) ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfTmShell(" + IdToString( nParentId) + "," + IdToString( nSurfId) + "," + ToString( dThick) + "," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco il risultato return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBezier( int nParentId, int nDegU, int nDegV, int nSpanU, int nSpanV, const PNTVECTOR& vPnt, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // il numero dei punti deve essere pari al prodotto dei gradi per gli span + 1 int nDim = ( nDegU * nSpanU + 1) * ( nDegV * nSpanV + 1) ; bOk = bOk && ( vPnt.size() == nDim) ; // recupero il riferimento di immersione della superficie Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // creo la superficie di Bezier PtrOwner pSurfBez( CreateSurfBezier()) ; bOk = bOk && ! IsNull( pSurfBez) ; // inizializzo la superficie di Bezier bOk = bOk && pSurfBez->Init( nDegU, nDegV, nSpanU, nSpanV, false) ; // setto i punti di controllo for ( int i = 0 ; i < nDim && bOk ; ++ i) { // eventuale trasformazione del punto nel riferimento locale Point3d ptCtrl = GetPointLocal( pGeomDB, vPnt[i], nRefType, frLoc) ; // inserimento del punto di controllo if ( ! pSurfBez->SetControlPoint( i, ptCtrl)) bOk = false ; } // se superficie nulla (ovvero ridotta a punto), errore bOk = bOk && ! pSurfBez->IsAPoint() ; // inserisco la superficie nel DB int nId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSurfBez)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sPC ; for ( size_t i = 0 ; i < vPnt.size() ; ++ i) { sPC += ( i == 0 ? "{" : ",{") + ToString( vPnt[i]) + "}" ; } string sLua = "EgtSurfBezier(" + IdToString( nParentId) + "," + ToString( nDegU) + "," + ToString( nDegV) + "," + ToString( nSpanU) + "," + ToString( nSpanV) + ",{" + sPC + "}," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBezierRational( int nParentId, int nDegU, int nDegV, int nSpanU, int nSpanV, const PNTUVECTOR& vPntW, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // il numero dei punti deve essere pari al prodotto dei gradi per gli span + 1 int nDim = ( nDegU * nSpanU + 1) * ( nDegV * nSpanV + 1) ; bOk = bOk && ( vPntW.size() == nDim) ; // recupero il riferimento di immersione della superficie Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // creo la superficie di Bezier PtrOwner pSurfBez( CreateSurfBezier()) ; bOk = bOk && ! IsNull( pSurfBez) ; // inizializzo la superficie di Bezier bOk = bOk && pSurfBez->Init( nDegU, nDegV, nSpanU, nSpanV, true) ; // setto i punti di controllo for ( int i = 0 ; i < nDim && bOk ; ++ i) { // eventuale trasformazione del punto nel riferimento locale Point3d ptCtrl = GetPointLocal( pGeomDB, vPntW[i].first, nRefType, frLoc) ; // inserimento del punto di controllo if ( ! pSurfBez->SetControlPoint( i, ptCtrl, vPntW[i].second)) bOk = false ; } // se superficie nulla (ovvero ridotta a punto), errore bOk = bOk && ! pSurfBez->IsAPoint() ; // inserisco la superficie nel DB int nId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSurfBez)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sPC ; for ( size_t i = 0 ; i < vPntW.size() ; ++ i) { sPC += ( i == 0 ? "{" : ",{") + ToString( vPntW[i].first, vPntW[i].second) + "}" ; } string sLua = "EgtSurfBezierRat(" + IdToString( nParentId) + "," + ToString( nDegU) + "," + ToString( nDegV) + "," + ToString( nSpanU) + "," + ToString( nSpanV) + ",{" + sPC + "}," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBezierLeaves( int nParentId, int nSurfBzId, int nTextHeight, bool bShowTrim, bool bRefined, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero la superficie const ISurfBezier* pSurfBez = GetSurfBezier( pGeomDB->GetGeoObj( nSurfBzId)) ; if ( pSurfBez == nullptr) return GDB_ID_NULL ; // disegno le foglie vector> vLeaves ; pSurfBez->GetLeaves( vLeaves, bRefined) ; double dFactor = 1 ; int nFirstId = GDB_ID_NULL ; int nCount = 0 ; for ( int k = 0 ; k < (int)vLeaves.size() ; ++ k) { Point3d ptBL = get<1>( vLeaves[k]) * dFactor ; Point3d ptTR = get<2>( vLeaves[k]) * dFactor ; Point3d ptBR( ptTR.x, ptBL.y) ; Point3d ptTL( ptBL.x, ptTR.y) ; PolyLine PL ; PL.AddUPoint( 0, ptBL) ; PL.AddUPoint( 1, ptBR) ; PL.AddUPoint( 2, ptTR) ; PL.AddUPoint( 3, ptTL) ; PL.Close() ; // creo la curva e la inserisco nel GDB PtrOwner pCrvCompo( CreateCurveComposite()) ; if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( PL) || ! pCrvCompo->SetExtrusion( Z_AX)) return GDB_ID_NULL ; // inserisco la curva composita nel DB int nCrvId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pCrvCompo)) ; if ( nCrvId == GDB_ID_NULL) return GDB_ID_NULL ; ++ nCount ; if ( nFirstId == GDB_ID_NULL) nFirstId = nCrvId ; // creo il testo e lo riempio string sText = ToString( get<0>( vLeaves[k])) ; Point3d ptCenter( ( ptBL + ptTR) / 2) ; PtrOwner pTXT( CreateExtText()) ; if ( IsNull( pTXT) || ! pTXT->Set( ptCenter, Z_AX, X_AX, sText, "", false, nTextHeight)) return GDB_ID_NULL ; // inserisco il testo nel DB int nTxtId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pTXT)) ; if ( nTxtId == GDB_ID_NULL) return GDB_ID_NULL ; ++ nCount ; } // se richiesto disegno la regione di trim const ISurfFlatRegion* pSfr = pSurfBez->GetTrimRegion() ; if ( bShowTrim && pSfr != nullptr) { PtrOwner pTrimReg( pSfr->Clone()) ; if ( ! IsNull( pTrimReg)) { int nTrimId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pTrimReg)) ; if ( nTrimId == GDB_ID_NULL) return GDB_ID_NULL ; ++ nCount ; } } // restituisco i risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBezierTria2D( int nParentId, int nSurfBzId, int nTextHeight, bool bShowTrim, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero la superficie const ISurfBezier* pSurfBez = GetSurfBezier( pGeomDB->GetGeoObj( nSurfBzId)) ; if ( pSurfBez == nullptr) return GDB_ID_NULL ; // disegno i triangoli vector> vTria2D ; pSurfBez->GetTriangles2D( vTria2D) ; int nFirstId = GDB_ID_NULL ; int nCount = 0 ; bool bOk = true ; for ( int k = 0 ; k < (int)vTria2D.size() ; ++ k) { PtrOwner pStm( CreateSurfTriMesh()) ; bOk = bOk && ! IsNull( pStm) ; Point3d ptP1L = get<1>(vTria2D[k]) ; Point3d ptP2L = get<2>(vTria2D[k]) ; Point3d ptP3L = get<3>(vTria2D[k]) ; // assegno il triangolo if ( bOk) { pStm->Init( 3, 1, 1) ; int vV[3]{ pStm->AddVertex( ptP1L), pStm->AddVertex( ptP2L), pStm->AddVertex( ptP3L)} ; bOk = ( pStm->AddTriangle( vV) != SVT_NULL) && pStm->AdjustTopology() ; } // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStm)) : GDB_ID_NULL) ; if ( nNewId == GDB_ID_NULL) return GDB_ID_NULL ; if ( nFirstId == GDB_ID_NULL) nFirstId = nNewId ; ++ nCount ; // creo il testo e lo riempio string sText = ToString( get<0>( vTria2D[k])) ; Point3d ptCenter( ( ptP1L + ptP2L + ptP3L) / 3) ; PtrOwner pTXT( CreateExtText()) ; if ( IsNull( pTXT) || ! pTXT->Set( ptCenter, Z_AX, X_AX, sText, "", false, nTextHeight)) return GDB_ID_NULL ; // inserisco il testo nel DB int nTxtId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pTXT)) ; if ( nTxtId == GDB_ID_NULL) return GDB_ID_NULL ; ++ nCount ; } // se richiesto disegno la regione di trim const ISurfFlatRegion* pSfr = pSurfBez->GetTrimRegion() ; if ( bShowTrim && pSfr != nullptr) { PtrOwner pTrimReg( pSfr->Clone()) ; if ( ! IsNull( pTrimReg)) { int nTrimId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pTrimReg)) ; if ( nTrimId == GDB_ID_NULL) return GDB_ID_NULL ; ++ nCount ; } } // restituisco i risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //------------------------------------------------------------------------------- int ExeCreateBezierSphere( int nParentId, const Point3d& ptCenter, double dR, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento di immersione della superficie Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // reucpero il punto in locale Point3d ptCenterLoc = GetPointLocal( pGeomDB, ptCenter, nRefType, frLoc) ; // Creo la superficie PtrOwner pSurfBez( GetSurfBezierSphere( ptCenterLoc, dR)) ; bOk = bOk && ! IsNull( pSurfBez) ; int nId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSurfBez)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBzSphere(" + IdToString( nParentId) + "," + ToString( ptCenter) + "," + ToString( dR) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // resituisco l'identificativo dell'entità creata return nId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBzByFlatContour( int nParentId, int nCrvId, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero la curva in locale CurveLocal CrvLoc( pGeomDB, nCrvId, frLoc) ; bOk = bOk && ( CrvLoc.Get() != nullptr) ; // calcolo la superficie PtrOwner pSbz( bOk ? GetSurfBezierByFlatContour( CrvLoc, dLinTol) : nullptr) ; bOk = bOk && ! IsNull( pSbz) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbz)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBzByFlatContour(" + IdToString( nParentId) + "," + ToString( nCrvId) + "," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBzByRegion( int nParentId, const INTVECTOR& vCrvIds, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero le curve in locale CURVELOCALVECTOR vCrvLoc ; vCrvLoc.reserve( vCrvIds.size()) ; CICURVEPVECTOR vCrvP ; vCrvP.reserve( vCrvIds.size()) ; for ( size_t i = 0 ; i < vCrvIds.size() ; ++ i) { int nId = (( vCrvIds[i] != GDB_ID_SEL) ? vCrvIds[i] : pGeomDB->GetFirstSelectedObj()) ; while ( nId != GDB_ID_NULL) { vCrvLoc.emplace_back( pGeomDB, nId, frLoc) ; vCrvP.push_back( vCrvLoc.back().Get()) ; bOk = bOk && ( vCrvLoc[i].Get() != nullptr) ; // passo al successivo nId = (( vCrvIds[i] != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ; } } // calcolo la superficie PtrOwner pSbz( bOk ? GetSurfBezierByRegion( vCrvP, dLinTol) : nullptr) ; bOk = bOk && ! IsNull( pSbz) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbz)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBzByRegion(" + IdToString( nParentId) + ",{" + IdListToString( vCrvIds) + "}," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBzByExtrusion( int nParentId, int nCrvId, const Vector3d& vtExtr, bool bCapEnds, double dLinTol, int nRefType, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero il riferimento della curva Frame3d frCrv ; bOk = bOk && pGeomDB->GetGlobFrame( nCrvId, frCrv) ; // recupero la curva in locale const ICurve* pCrvOrig = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ; PtrOwner pCrv( pCrvOrig->Clone()) ; // porto in locale il vettore estrusione Vector3d vtExtrL = GetVectorLocal( pGeomDB, vtExtr, nRefType, frLoc) ; // creo la superficie e la inserisco nel DB double dAndTolStdDeg = 15 ; Plane3d plPlane ; double dArea ; PolyLine plApprox ; pCrv->ApproxWithLines( dLinTol, dAndTolStdDeg, ICurve::APL_STD, plApprox) ; double dOrthoExtr = 0 ; if ( bCapEnds && plApprox.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL)){ dOrthoExtr = plPlane.GetVersN() * vtExtrL ; if ( ( abs( dOrthoExtr) < EPS_SMALL)) return GDB_ID_NULL ; if ( dOrthoExtr < 0) pCrv->Invert() ; } // creo l'estrusione della curva PtrOwner pSbz( bOk ? GetSurfBezierByExtrusion( pCrv, vtExtrL, false, dLinTol) : nullptr ) ; bOk = bOk && ! IsNull( pSbz) ; // inserisco la superficie nel DB int nFirstId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbz)) : GDB_ID_NULL) ; bOk = bOk && ( nFirstId != GDB_ID_NULL) ; int nCount = ( bOk ? 1 : 0) ; // se richiesta chiusura agli estremi if ( bOk && bCapEnds) { PtrOwner pSrfBzTop( CreateSurfBezier()) ; bOk = ( ! IsNull( pSrfBzTop) && pSrfBzTop->CreateByFlatContour( plApprox) && pSrfBzTop->Translate( vtExtrL)) ; int nTopId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzTop)) : GDB_ID_NULL) ; PtrOwner pSrfBzBottom( CreateSurfBezier()) ; bOk = ( ! IsNull( pSrfBzBottom) && pSrfBzBottom->CreateByFlatContour( plApprox) && pSrfBzBottom->Invert()) ; int nBotId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzBottom)) : GDB_ID_NULL) ; if ( nTopId == GDB_ID_NULL || nBotId == GDB_ID_NULL) { pGeomDB->Erase( nFirstId) ; pGeomDB->Erase( nTopId) ; pGeomDB->Erase( nBotId) ; nFirstId = GDB_ID_NULL ; nCount = 0 ; } } if ( pnCount != nullptr) *pnCount = nCount ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBzByExtrusion(" + IdToString( nParentId) + "," + IdToString( nCrvId) + ",{" + ToString( vtExtr) + "}," + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nFirstId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBzByRegionExtrusion( int nParentId, const INTVECTOR& vCrvIds, const Vector3d& vtExtr, bool bCapEnds, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero le curve in locale CURVELOCALVECTOR vCrvLoc ; vCrvLoc.reserve( vCrvIds.size()) ; CICURVEPVECTOR vCrvP ; vCrvP.reserve( vCrvIds.size()) ; for ( size_t i = 0 ; i < vCrvIds.size() ; ++ i) { int nId = (( vCrvIds[i] != GDB_ID_SEL) ? vCrvIds[i] : pGeomDB->GetFirstSelectedObj()) ; while ( nId != GDB_ID_NULL) { vCrvLoc.emplace_back( pGeomDB, nId, frLoc) ; vCrvP.push_back( const_cast( vCrvLoc.back().Get())) ; bOk = bOk && ( vCrvLoc[i].Get() != nullptr) ; // passo al successivo nId = (( vCrvIds[i] != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ; } } // porto in locale il vettore estrusione Vector3d vtExtrL = GetVectorLocal( pGeomDB, vtExtr, nRefType, frLoc) ; // creo le superfici e le inserisco nel DB int nFirstId = GDB_ID_NULL ; double dAndTolStdDeg = 15 ; // riordino le curve in modo che la prima sia quella esterna e tutte le altre dopo POLYLINEVECTOR vPL ; for ( int i = 0 ; i < int( vCrvP.size()) ; ++ i) { vPL.emplace_back() ; if ( ! vCrvP[i]->ApproxWithLines( dLinTol, dAndTolStdDeg, ICurve::APL_SPECIAL, vPL.back())) return false ; } Vector3d vtN ; INTMATRIX vnPLIndMat ; BOOLVECTOR vbInvert ; if ( ! CalcRegionPolyLines( vPL, vtN, vnPLIndMat, vbInvert)) return nFirstId ; // creo una copia delle curve, orientate giuste ICURVEPOVECTOR vpCrvOr ; for (int i = 0 ; i < int( vnPLIndMat.size()) ; ++i) { for ( int j = 0 ; j< int( vnPLIndMat[i].size()) ; ++j) { vpCrvOr.emplace_back( vCrvP[vnPLIndMat[i][j]]->Clone()) ; if ( vbInvert[vnPLIndMat[i][j]]) vpCrvOr.back()->Invert() ; } } // controlo se il vettore di estrusione è orientato come la normale della curva più grande o no bool bOrientedAsExtrusion = false ; Plane3d plPlane ; double dArea ; double dOrthoExtr = 0 ; // verifico che la curva sia chiusa e piatta if ( vPL[0].IsClosedAndFlat(plPlane, dArea, dLinTol)) { dOrthoExtr = plPlane.GetVersN() * vtExtr ; // controllo che ci sia una componente dell'estrusione perpendicolare al piano della curva if ( abs( dOrthoExtr) < EPS_SMALL) return GDB_ID_NULL ; if ( dOrthoExtr > EPS_SMALL) bOrientedAsExtrusion = true ; } else bCapEnds = false ; // creo l'estrusione delle curve for ( int i = 0 ; i < int( vpCrvOr.size()) ; ++ i) { // calcolo la superficie ISurfBezier* pSbz = ( bOk ? GetSurfBezierByExtrusion( vpCrvOr[i], vtExtrL, false, dLinTol) : nullptr ) ; if ( ! bOrientedAsExtrusion) pSbz->Invert() ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSbz) : GDB_ID_NULL) ; bOk = bOk && ( nNewId != GDB_ID_NULL) ; if ( bOk && nFirstId == GDB_ID_NULL) nFirstId = nNewId ; } // se richiesta chiusura agli estremi if ( bCapEnds) { PtrOwner pSrfBzTop( CreateSurfBezier()) ; pSrfBzTop->CreateByRegion( vPL) ; pSrfBzTop->Translate( vtExtrL) ; if ( ! bOrientedAsExtrusion) pSrfBzTop->Invert() ; pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzTop)) ; PtrOwner pSrfBzBottom( CreateSurfBezier()) ; pSrfBzBottom->CreateByRegion( vPL) ; if ( bOrientedAsExtrusion) pSrfBzBottom->Invert() ; pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzBottom)) ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBzByRegionExtrusion(" + IdToString( nParentId) + ",{" + IdListToString( vCrvIds) + "},{" + ToString( vtExtr) + "}," + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nFirstId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nFirstId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBzByScrewing( int nParentId, int nCrvId, const Point3d& ptAx, const Vector3d& vtAx, double dAngRotDeg, double dMove, bool bCapEnds, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero la curva in locale CurveLocal CrvLoc( pGeomDB, nCrvId, frLoc) ; bOk = bOk && ( CrvLoc.Get() != nullptr) ; // porto in locale punto e vettore asse Point3d ptAxL = GetPointLocal( pGeomDB, ptAx, nRefType, frLoc) ; Vector3d vtAxL = GetVectorLocal( pGeomDB, vtAx, nRefType, frLoc) ; vtAxL.Normalize() ; // la curva che fa da sezione alla superficie è chiusa e piana ed è richiesto il capping verifico se la superficie è da invertire // lo screwing non deve essere una semplice rivoluzione bool bOrientedAsScrewing = false ; Plane3d plPlane ; double dArea = 0 ; double dAngTolDeg = 15 ; PolyLine pl ; CrvLoc->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, pl) ; if ( pl.IsClosedAndFlat( plPlane, dArea, dLinTol) && ! (abs(abs(dAngRotDeg) - ANG_FULL) < EPS_SMALL && abs( dMove) < EPS_SMALL)) { double dOrthoMove = plPlane.GetVersN() * vtAxL * dMove ; if( bCapEnds) { // se la curva sta in un piano passante per l'asse allora devo fare qualche conto per capire come è orientata if( abs( dOrthoMove) < EPS_SMALL) { // ruoto il centroide della curva di un minimo angolo e poi controllo se mi sono spostato in verso concorde alla normale al piano della curva Point3d ptCen ; CrvLoc->GetCentroid( ptCen) ; Point3d ptCenRot = ptCen ; ptCenRot.Rotate( ptAxL, vtAxL, 2) ; Vector3d vtRot = ptCenRot - ptCen ; dOrthoMove = vtRot * plPlane.GetVersN() ; } if ( dOrthoMove > EPS_SMALL) bOrientedAsScrewing = true ; } } else bCapEnds = false ; // calcolo la superficie PtrOwner pSbz( bOk ? GetSurfBezierByScrewing( CrvLoc, ptAxL, vtAxL, dAngRotDeg, dMove, bCapEnds, dLinTol) : nullptr) ; bOk = bOk && ! IsNull( pSbz) ; if ( ! bOrientedAsScrewing && bCapEnds && bOk) pSbz->Invert() ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbz)) : GDB_ID_NULL) ; // se richiesto creo anche i cap if ( bCapEnds && bOk) { ISurfBezier* pSbzBase1 = GetSurfBezierByFlatContour(CrvLoc,dLinTol) ; if ( bOrientedAsScrewing) pSbzBase1->Invert() ; bOk = bOk && pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSbzBase1) ; ISurfBezier* pSbzBase2 = GetSurfBezierByFlatContour( CrvLoc,dLinTol) ; pSbzBase2->Translate( vtAxL * dMove) ; pSbzBase2->Rotate( ptAxL, vtAxL, dAngRotDeg) ; if( ! bOrientedAsScrewing) pSbzBase2->Invert() ; bOk = bOk && pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSbzBase2) ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfbzByScrewing(" + IdToString( nParentId) + "," + ToString( nCrvId) + ",{" + ToString( ptAx) + "},{" + ToString( vtAx) + "}," + ToString( dAngRotDeg) + "," + ToString( dMove) + "," + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBzByRevolve( int nParentId, int nCrvId, const Point3d& ptAx, const Vector3d& vtAx, bool bCapEnds, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero la curva in locale CurveLocal CrvLoc( pGeomDB, nCrvId, frLoc) ; bOk = bOk && ( CrvLoc.Get() != nullptr) ; // porto in locale punto e vettore asse Point3d ptAxL = GetPointLocal( pGeomDB, ptAx, nRefType, frLoc) ; Vector3d vtAxL = GetVectorLocal( pGeomDB, vtAx, nRefType, frLoc) ; // calcolo la superficie PtrOwner pSbz (( bOk ? GetSurfBezierByRevolve( CrvLoc, ptAxL, vtAxL, bCapEnds, dLinTol) : nullptr)) ; if( IsNull( pSbz) || ! pSbz->IsValid()) return GDB_ID_NULL ; // controllo se devo invertire la superficie Point3d ptStart ; CrvLoc->GetStartPoint( ptStart) ; DistPointLine dplS( ptStart, ptAxL, vtAxL, 1, false) ; double dDistS = 0 ; dplS.GetDist( dDistS) ; bool bStartOnAx = dDistS > EPS_SMALL ; Point3d ptEnd ; CrvLoc->GetEndPoint( ptEnd) ; DistPointLine dplE( ptEnd, ptAxL, vtAxL, 1, false) ; double dDistE = 0 ; dplE.GetDist( dDistE) ; bool bEndOnAx = dDistE > EPS_SMALL ; Vector3d vtDir = ptEnd - ptStart ; double dParallel = vtDir * vtAxL ; if ( dParallel > EPS_SMALL) pSbz->Invert() ; // finché non ho le SurfCompo creo qui i cap if ( bCapEnds && bOk) { // calcola il bbox della superficie BBox3d bbox3dSurf ; int nDegU, nDegV, nSpanU, nSpanV ; bool bTrim, bRat ; pSbz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bTrim, bRat) ; int nPointCount = ( nDegU * nSpanU + 1) * ( nDegV * nSpanV + 1) ; for ( int p = 0 ; p < nPointCount ; ++p) { bool bPointOk = true ; Point3d ptCtrl = pSbz->GetControlPoint( p, &bPointOk) ; bbox3dSurf.Add( ptCtrl) ; } // recupero i loop ICRVCOMPOPOVECTOR vCCLoop(2) ; vCCLoop[0].Set(pSbz->GetSingleEdge3D( true, 1)) ; vCCLoop[1].Set(pSbz->GetSingleEdge3D( true, 3)) ; // controllo se i loop trovati sono validi bool bValidLoop1 = false ; bool bValidLoop3 = false ; if( ! IsNull(vCCLoop[0]) && vCCLoop[0]->IsValid()) bValidLoop1 = true ; if( ! IsNull(vCCLoop[1]) && vCCLoop[1]->IsValid()) bValidLoop3 = true ; if( ! IsNull(vCCLoop[0]) && ! vCCLoop[0]->IsValid() && ! bStartOnAx) return GDB_ID_NULL ; if( ! IsNull(vCCLoop[1]) && ! vCCLoop[1]->IsValid() && ! bEndOnAx) return GDB_ID_NULL ; // il getLoops per superfici non trimmate restituisce 1 elemento per ogni lato dello spazio parametrico. // in questo caso la superficie è chiusa lungo il parametro V, quindi i lati 0 e 2 saranno null. double dAngTolDeg = 5 ; PolyLine plEdge1 ; if( bValidLoop1) vCCLoop[0]->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plEdge1) ; PolyLine plEdge3 ; if( bValidLoop3) vCCLoop[1]->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plEdge3) ; // devo distinguere tra il loop superiore e quello inferiore Point3d ptCen ; Vector3d vtN ; Plane3d plPlane ; double dArea ; if( bValidLoop1){ bOk = bOk && plEdge1.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL) ; vtN = plPlane.GetVersN() ; // vedo come questa normale è orientata rispetto alla bbox della superficie vCCLoop[0]->GetCentroid( ptCen) ; ptCen += vtN ; if ( bbox3dSurf.Encloses( ptCen)) plEdge1.Invert() ; } if ( bValidLoop3) { bOk = bOk && plEdge3.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL) ; vtN = plPlane.GetVersN() ; // vedo come questa normale è orientata rispetto alla bbox della superficie vCCLoop[1]->GetCentroid( ptCen) ; ptCen += vtN ; if ( bbox3dSurf.Encloses( ptCen)) plEdge3.Invert() ; } // creo le superfici e le inserisco nel DB if( bValidLoop1) { PtrOwner pSrfBzCap1( CreateSurfBezier()) ; pSrfBzCap1->CreateByFlatContour( plEdge1) ; pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzCap1)) ; } if( bValidLoop3) { PtrOwner pSrfBzCap3( CreateSurfBezier()) ; pSrfBzCap3->CreateByFlatContour( plEdge3) ; pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzCap3)) ; } } // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbz)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBzByRevolve(" + IdToString( nParentId) + "," + ToString( nCrvId) + ",{" + ToString( ptAx) + "},{" + ToString( vtAx) + "}," + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + "," + RefTypeToString( nRefType) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBzRuled( int nParentId, int nCrvId1, int nCrvId2, int nRuledType, bool bCapEnds, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero le curve in locale CurveLocal CrvLoc1( pGeomDB, nCrvId1, frLoc) ; bOk = bOk && ( CrvLoc1.Get() != nullptr) ; CurveLocal CrvLoc2( pGeomDB, nCrvId2, frLoc) ; bOk = bOk && ( CrvLoc2.Get() != nullptr) ; // calcolo la superficie PtrOwner pSbz( bOk ? GetSurfBezierRuled( CrvLoc1, CrvLoc2, nRuledType, dLinTol) : nullptr) ; bOk = bOk && ! IsNull( pSbz) ; // verifiche per orientamento se con tappi bool bWithCaps = false ; bool bStdOrient = true ; Plane3d plPlane1, plPlane2 ; double dArea1, dArea2 ; if ( bOk && bCapEnds && CrvLoc1->IsClosed() && CrvLoc2->IsClosed() && CrvLoc1->GetArea( plPlane1, dArea1) && CrvLoc2->GetArea( plPlane2, dArea2)) { bWithCaps = true ; Point3d ptStart1 ; CrvLoc1->GetStartPoint( ptStart1) ; Point3d ptStart2 ; CrvLoc2->GetStartPoint( ptStart2) ; Vector3d vtRuling = ptStart2 - ptStart1 ; bStdOrient = ( vtRuling * plPlane1.GetVersN() > 0) ; if ( ! bStdOrient) pSbz->Invert() ; } // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbz)) : GDB_ID_NULL) ; // se richiesto inserisco anche il cap if ( bOk && bWithCaps) { // costruisco la superficie dalla curva 1 PtrOwner pSbzFlat1( CreateSurfBezier()) ; double dAngTolDeg = 5 ; PolyLine pl1 ; CrvLoc1->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, pl1) ; pSbzFlat1->CreateByFlatContour( pl1) ; if ( bStdOrient) pSbzFlat1->Invert() ; // inserisco la superficie nel DB bOk = bOk && pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbzFlat1)) ; // costruisco la superficie dalla curva 2 PtrOwner pSbzFlat2( CreateSurfBezier()) ; PolyLine pl2 ; CrvLoc2->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, pl2) ; pSbzFlat2->CreateByFlatContour( pl2) ; if ( ! bStdOrient) pSbzFlat2->Invert() ; // inserisco la superficie nel DB bOk = bOk && pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbzFlat2)) ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBzRuled(" + IdToString( nParentId) + "," + ToString( nCrvId1) + "," + ToString( nCrvId2) + "," + ToString( nRuledType) + "," + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBzRuledGuided( int nParentId, int nCrvId1, int nCrvId2, const BIPNTVECTOR& vGuidesCrv, bool bCapEnds, double dLinTol, int nLayGuides) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero le curve in locale CurveLocal CrvLoc1( pGeomDB, nCrvId1, frLoc) ; bOk = bOk && ( CrvLoc1.Get() != nullptr) ; CurveLocal CrvLoc2( pGeomDB, nCrvId2, frLoc) ; bOk = bOk && ( CrvLoc2.Get() != nullptr) ; BIPNTVECTOR vCrv ; if( nLayGuides != -1 && vGuidesCrv.empty()) { int nId = pGeomDB->GetFirstInGroup( nLayGuides) ; while( nId != GDB_ID_NULL && bOk) { CurveLocal CrvLocGuide( pGeomDB, nId, frLoc) ; bOk = bOk && ( CrvLocGuide.Get() != nullptr) ; const ICurve* pCrv = CrvLocGuide.Get() ; Point3d ptStart ; pCrv->GetStartPoint( ptStart) ; ptStart.ToLoc( frLoc) ; Point3d ptEnd ; pCrv->GetEndPoint( ptEnd) ; ptEnd.ToLoc( frLoc) ; vCrv.emplace_back( ptStart, ptEnd) ; nId = pGeomDB->GetNext( nId) ; } } else if( ! vGuidesCrv.empty()) { for( int i = 0 ; i < ssize( vGuidesCrv) ; ++i) vCrv.emplace_back( GetToLoc( vGuidesCrv[i].first, frLoc), GetToLoc( vGuidesCrv[i].second, frLoc)) ; } else return GDB_ID_NULL ; // calcolo la superficie PtrOwner pSbz( bOk ? GetSurfBezierRuledGuided( CrvLoc1, CrvLoc2, vCrv, dLinTol) : nullptr) ; bOk = bOk && ! IsNull( pSbz) ; // verifiche per orientamento se con tappi bool bWithCaps = false ; bool bStdOrient = true ; Plane3d plPlane1, plPlane2 ; double dArea1, dArea2 ; if ( bOk && bCapEnds && CrvLoc1->IsClosed() && CrvLoc2->IsClosed() && CrvLoc1->GetArea( plPlane1, dArea1) && CrvLoc2->GetArea( plPlane2, dArea2)) { bWithCaps = true ; Point3d ptStart1 ; CrvLoc1->GetStartPoint( ptStart1) ; Point3d ptStart2 ; CrvLoc2->GetStartPoint( ptStart2) ; Vector3d vtRuling = ptStart2 - ptStart1 ; bStdOrient = ( vtRuling * plPlane1.GetVersN() > 0) ; if ( ! bStdOrient) pSbz->Invert() ; } // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbz)) : GDB_ID_NULL) ; // se richiesto inserisco anche il cap if ( bOk && bWithCaps) { // costruisco la superficie dalla curva 1 PtrOwner pSbzFlat1( CreateSurfBezier()) ; double dAngTolDeg = 5 ; PolyLine pl1 ; CrvLoc1->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, pl1) ; pSbzFlat1->CreateByFlatContour( pl1) ; if ( bStdOrient) pSbzFlat1->Invert() ; // inserisco la superficie nel DB bOk = bOk && pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbzFlat1)) ; // costruisco la superficie dalla curva 2 PtrOwner pSbzFlat2( CreateSurfBezier()) ; PolyLine pl2 ; CrvLoc2->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, pl2) ; pSbzFlat2->CreateByFlatContour( pl2) ; if ( ! bStdOrient) pSbzFlat2->Invert() ; // inserisco la superficie nel DB bOk = bOk && pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbzFlat2)) ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBzRuledGuided(" + IdToString( nParentId) + "," + ToString( nCrvId1) + "," + ToString( nCrvId2) + "," + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBzSkinned( int nParentId, const INTVECTOR& vCrvIds, bool bCapEnds, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero le curve in locale CURVELOCALVECTOR vCrvLoc ; vCrvLoc.reserve( vCrvIds.size()) ; CICURVEPVECTOR vCrvP ; vCrvP.reserve( vCrvIds.size()) ; for ( size_t i = 0 ; i < vCrvIds.size() ; ++ i) { int nId = vCrvIds[i] ; vCrvLoc.emplace_back( pGeomDB, nId, frLoc) ; vCrvP.push_back( vCrvLoc.back().Get()) ; bOk = bOk && ( vCrvLoc[i].Get() != nullptr) ; } // calcolo la superficie PtrOwner pSbz( bOk ? GetSurfBezierSkinned( vCrvP, dLinTol) : nullptr ) ; bOk = bOk && ! IsNull( pSbz) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbz)) : GDB_ID_NULL) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBzSkinned(" + IdToString( nParentId) + ",{" + IdListToString( vCrvIds) + "}," + ( bCapEnds ? "true" : "false") + "," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; } //------------------------------------------------------------------------------- int ExeCreateSurfBzSwept( int nParentId, int nSectId, int nGuideId, const Vector3d& vtAx, bool bCapEnds, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; bool bOk = true ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero le curve in locale CurveLocal CrvSect( pGeomDB, nSectId, frLoc) ; CurveLocal CrvGuide( pGeomDB, nGuideId, frLoc) ; // porto in locale vettore asse Vector3d vtAxL = GetVectorLocal( pGeomDB, vtAx, nRefType, frLoc) ; PolyLine plGuide ; double dAngTolDeg = 15 ; CrvGuide->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plGuide) ; Plane3d plPlane ; bool bFlatGuide = plGuide.IsFlat( plPlane) ; // calcolo la superficie PtrOwner pSbz( CreateSurfBezier()) ; if( bFlatGuide) pSbz.Set( bOk ? GetSurfBezierSweptInPlane( CrvSect, CrvGuide, vtAxL, bCapEnds, dLinTol) : nullptr ) ; else pSbz.Set( bOk ? GetSurfBezierSwept3d( CrvSect, CrvGuide, vtAxL, bCapEnds, dLinTol) : nullptr ) ; // se richiesto il capping verifico che la superficie abbia il gisto orientamento bool bOrientedAsGuide = false ; ICRVCOMPOPOVECTOR vCCLoop ; if( bCapEnds) { // controlo se il vettore di start della guida è orientato come la normale della curva o no Vector3d vtStart ; CrvGuide->GetStartDir( vtStart) ; Plane3d plPlane ; double dArea ; double dOrthoGuide = 0 ; // verifico che la curva sia chiusa e piatta PolyLine PL ; CrvSect->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, PL) ; if ( PL.IsClosedAndFlat(plPlane, dArea, dLinTol)) { dOrthoGuide = plPlane.GetVersN() * vtStart ; // controllo che ci sia una componente dell'estrusione perpendicolare al piano della curva if( abs( dOrthoGuide) < EPS_SMALL) return GDB_ID_NULL ; // recupero i loop pSbz->GetLoops( vCCLoop, true) ; // se necessario inverto la superficie if( dOrthoGuide > EPS_SMALL) bOrientedAsGuide = true ; else pSbz->Invert() ; } else bCapEnds = false ; } // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbz)) : GDB_ID_NULL) ; // se richiesto aggiungo anche i cap if ( bCapEnds) { // controllo se i loop trovati sono validi bool bValidLoop0 = false ; bool bValidLoop2 = false ; if( ! IsNull(vCCLoop[0]) && vCCLoop[0]->IsValid()) bValidLoop0 = true ; if( ! IsNull(vCCLoop[2]) && vCCLoop[2]->IsValid()) bValidLoop2 = true ; if( ! IsNull(vCCLoop[0]) && ! vCCLoop[0]->IsValid()) return GDB_ID_NULL ; if( ! IsNull(vCCLoop[2]) && ! vCCLoop[2]->IsValid()) return GDB_ID_NULL ; // il getLoops per superfici non trimmate restituisce 1 elemento per ogni lato dello spazio parametrico. // in questo caso la superficie è chiusa lungo il parametro V, quindi i lati 1 e 3 saranno null. double dAngTolDeg = 5 ; PolyLine plEdge0 ; if( bValidLoop0) vCCLoop[0]->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plEdge0) ; PolyLine plEdge2 ; if( bValidLoop2) vCCLoop[2]->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plEdge2) ; PtrOwner pSrfBezStart( CreateSurfBezier()) ; pSrfBezStart->CreateByFlatContour( plEdge2) ; // se necessario inverto if( bOrientedAsGuide) // edge 2, che è la prima riga della matrice dei punti di controllo è orientato nello stesso verso della curva di sezione pSrfBezStart->Invert() ; // aggiungo al database pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBezStart)) ; PtrOwner pSrfBezEnd( CreateSurfBezier()) ; pSrfBezEnd->CreateByFlatContour( plEdge0) ; // se necessario inverto if( bOrientedAsGuide) // edge 0, che è l'ultima riga della matrice dei punti di controllo è orientato in verso opposto alla curva di sezione pSrfBezEnd->Invert() ; // aggiungo al database pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBezEnd)) ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfbzByScrewing(" + IdToString( nParentId) + "," + IdToString( nSectId) + "," + IdToString( nGuideId) + "," + ToString( dLinTol) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della nuova entità return nNewId ; }