//---------------------------------------------------------------------------- // 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/EGkSurfFlatRegion.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EGkSurfTriMesh.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/EgtPointerOwner.h" #include "/EgtDev/Include/EGkExtText.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 ; } //------------------------------------------------------------------------------- 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) ; // eventuale traslazione per larghezza negativa if ( bOk && dWidth < 0) pSTM->Translate( Vector3d( dWidth, 0, 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 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 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 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, 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 ? GetSurfTriMeshSwept( 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 = "EgtSurfTmSwept(" + 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 sLua = "EgtSurfTmRuled(" + IdToString( nParentId) + "," + ToString( nPtOrCrvId1) + "," + ToString( nPtOrCrvId2) + "," + ( nType == ISurfTriMesh::RLT_MINDIST ? "'MD'" : "'IP'") + "," + 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 ExeCreateSurfTmBySurfBezier( int nParentId, int nSbezId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; // recupero la superficie di Bezier const ISurfBezier* pSbez = GetSurfBezier( pGeomDB->GetGeoObj( nSbezId)) ; bool bOk = ( pSbez != nullptr) ; // recupero il riferimento della superficie sorgente Frame3d frSou ; bOk = bOk && pGeomDB->GetGlobFrame( nSbezId, frSou) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // copio la superficie ausiliaria della Bezier const ISurfTriMesh* pAuxSurf = ( bOk ? pSbez->GetAuxSurf() : nullptr) ; PtrOwner pStm( pAuxSurf != nullptr ? pAuxSurf->Clone() : nullptr) ; bOk = bOk && ! IsNull( pStm) ; // la porto nel riferimento destinazione 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 = "EgtSurfTmBySurfBezier(" + IdToString( nParentId) + "," + IdToString( nSbezId) + ")" + " -- 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) ; // Costruttore di trimesh da insieme disordinato di triangoli StmFromTriangleSoup StmFts ; bOk = bOk && StmFts.Start() ; // recupero i triangoli del bordo dello Zmap int nCount = ( bOk ? pVZM->GetBlockCount() : 0) ; for ( int i = 0 ; i < nCount && bOk ; ++ i) { // recupero i triangoli del blocco TRIA3DEXVECTOR vTria ; pVZM->GetBlockTriangles( i, vTria) ; for ( auto& Tria : vTria) { // aggiusto per i sistemi di riferimento Tria.LocToLoc( frSou, frLoc) ; // inserisco il triangolo nella nuova superficie if ( ! StmFts.AddTriangle( Tria)) bOk = false ; } } // 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) ; 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 ; } //------------------------------------------------------------------------------- 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, 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) ; 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 ; }