/*****************************************************************************/ /* */ /* Funzioni aggiunte per integrare vroni con le nostre librerie */ /* Le funzioni modificate nel codice vengono individuate con il */ /* commento MODIF */ /*****************************************************************************/ #include "vroni_object.h" #include "offset.h" #include //---------------------------------------------------------------------------- void vroniObject::GetPointFromCoord( coord ptCoord, double p[3]) { // trasformo vroni::coord in un array compatibile con il nostro Point3d p[0] = ptCoord.x ; p[1] = ptCoord.y ; p[2] = 0.0 ; // scalo if ( unscaleXYZ) { p[0] = UnscaleX( p[0]) ; p[1] = UnscaleY( p[1]) ; } } //---------------------------------------------------------------------------- int vroniObject::GetOffsetCurveCount( int i) { return GetOffsetListEnd(i) - GetOffsetListStart(i) + 1 ; } //---------------------------------------------------------------------------- vr_bool vroniObject::GetOffsetCurve( int nOffs, int nCrv, int& nType, double ptS[3], double ptE[3], double ptC[3], int& nOrigLoop, int& nOrigCrv, int& nOrigPnt) { // sito originale nOrigLoop = -1 ; nOrigCrv = -1 ; nOrigPnt = -1 ; if ( nOffs > num_offset_list) return false ; int k = GetOffsetListStart( nOffs) + nCrv ; if ( k > GetOffsetListEnd( nOffs)) return false ; assert( InOffsetData(k)) ; // recupero il punto iniziale coord start = GetOffsetPntCoords( k) ; GetPointFromCoord( start, ptS) ; // recupero punto finale int m = k + 1 ; if ( m > GetOffsetListEnd( nOffs)) m = GetOffsetListStart( nOffs) ; coord end = GetOffsetPntCoords( m) ; GetPointFromCoord( end, ptE) ; if ( GetOffsetEleType( k) == PNT) { int c = GetOffsetEleSite( k) ; assert( InPntsList( c)) ; coord center = GetPntCoords( c) ; vr_bool ori = false ; if ( ScrutinizeArc( start, end, center, &ori, ZERO_IO, HasIncidentSite( c))) { nType = CW ; // recupero le coordinate del centro GetPointFromCoord( center, ptC) ; } else nType = SEG ; // recupero il sito nOrigLoop = pnts[c].ext_appl.first ; nOrigPnt = pnts[c].ext_appl.second ; } else if ( GetOffsetEleType( k) == SEG) { nType = SEG ; // recupero il sito int c = GetOffsetEleSite( k) ; nOrigLoop = segs[c].ext_appl.first ; nOrigCrv = segs[c].ext_appl.second ; } else if ( GetOffsetEleType( k) == CCW || GetOffsetEleType( k) == CW) { int c = GetOffsetEleSite( k) ; assert( InArcsList( c)) ; coord center = GetArcCenter( c) ; vr_bool ori = ( GetOffsetEleType( k) == CCW ? true : false) ; if ( ScrutinizeArc( start, end, center, &ori, ZERO_IO, true)) { nType = ori ? CCW : CW ; // recupero le coordinate del centro GetPointFromCoord( center, ptC) ; } else nType = SEG ; // recupero il sito nOrigLoop = arcs[c].ext_appl.first ; nOrigCrv = arcs[c].ext_appl.second ; } return true ; } //---------------------------------------------------------------------------- void vroniObject::ResetVoronoiDiagram(void) { /* */ /* reset global and static data within individual files */ /* */ #ifdef GRAPHICS if (graphics) { #if defined (OGL_GRAPHICS) ResetGraphicsData(); #else ExtApplResetGraphicsData; #endif ResetBufferData(); } #endif // sistemo i 4 punti estremi SetXCoord( 0, -DBL_MAX) ; SetYCoord( 0, -DBL_MAX) ; SetXCoord( 1, -DBL_MAX) ; SetYCoord( 1, DBL_MAX) ; int i = num_pnts - 2 ; SetXCoord( i, DBL_MAX) ; SetYCoord( i, -DBL_MAX) ; i = num_pnts - 1 ; SetXCoord( i, DBL_MAX) ; SetYCoord( i, DBL_MAX) ; ResetVDData(); ResetVDConstructionData(); ResetEdgeData(); ResetOffsetData(); #ifdef MAT ResetWMATStatus(); #endif ResetIntersectionData(); ResetIntersectionStatus(); ResetCleanStatus(); isolated_pnts = false; /* */ /* let the user call some application-specific function */ /* */ ExtApplFuncReset; return; } //---------------------------------------------------------------------------- BisectorType vroniObject::GetBisectorType( int i) { int lft, rgt ; t_site t_lft, t_rgt ; GetLftSiteData(i, &lft, &t_lft) ; GetRgtSiteData(i, &rgt, &t_rgt) ; BisectorType conic = NONE ; if ( t_lft == UNKNOWN || t_rgt == UNKNOWN || lft == NIL || rgt == NIL) return NONE ; if (( t_lft == PNT) && ( t_rgt == PNT)) return HYPERBOLA ; else if (( t_lft == PNT) || ( t_lft == ARC)) { if (( t_rgt == PNT) || ( t_rgt == ARC)) { if ( t_lft == PNT) { assert( t_rgt == ARC) ; assert( InArcsList( rgt)) ; if ( IsArcStartPnt( rgt, lft) || IsArcEndPnt( rgt, lft)) return LINE ; } if ( t_rgt == PNT) { assert( t_lft == ARC) ; assert( InArcsList( lft)) ; if ( IsArcStartPnt( lft, rgt) || IsArcEndPnt( lft, rgt)) return LINE ; } // verifico se degenere e_formula coeff ; if ( ! ComputeHyperbolaEllipseData( i, &coeff)) { double r1 = t_lft == PNT ? 0.0 : GetArcRadius( lft) ; coord p1 = t_lft == PNT ? GetPntCoords( lft) : GetArcCenter(lft) ; double r2 = t_rgt == PNT ? 0.0 : GetArcRadius( rgt) ; coord p2 = t_rgt == PNT ? GetPntCoords( rgt) : GetArcCenter(rgt) ; double dx = p2.x - p1.x ; double dy = p2.y - p1.y ; double dist = dx * dx + dy * dy ; if ( eq( dist, ZERO_MAX)) { dist = r1 - r2; if ( eq( dist, ZERO_MAX)) return LINE ; else // degenerate elliptic edge return DEGENERATE_HYPERELL ; } else return LINE ; } return HYPERELL ; } else { assert( t_rgt == SEG); assert( InSegsList( rgt)); if (( t_lft == PNT) && ( IsSegStartPnt( rgt, lft) || IsSegEndPnt( rgt, lft))) return LINE ; else { // verifico se degenere e_formula coeff ; if ( ! ComputeParabolaData( i, &coeff)) return LINE ; return PARABOLA ; } } } else { if (( t_rgt == PNT) || ( t_rgt == ARC)) { assert( t_lft == SEG) ; assert( InSegsList( lft)) ; if (( t_rgt == PNT) && ( IsSegStartPnt( lft, rgt) || IsSegEndPnt( lft, rgt))) return LINE ; else { // verifico se degenere e_formula coeff ; if ( ! ComputeParabolaData( i, &coeff)) return LINE ; return PARABOLA ; } } else { return LINE ; } } return conic ; } //---------------------------------------------------------------------------- vr_bool vroniObject::GetBisectorParams( int nEdge, double& dParS, double& dParE) { GetEdgeParam( nEdge, &dParS, &dParE) ; dParS = UnscaleV( dParS) ; dParE = UnscaleV( dParE) ; return true ; } //---------------------------------------------------------------------------- vr_bool vroniObject::GetBisectorPointAtParam( int nEdge, double dPar, double pt[3]) { // verifico se è necessario calcolare edges data if ( num_edge_data == 0) { int nTmp ; InitializeEdgeData( false, false, false, &nTmp) ; } coord p ; EvaluateBisectorData( nEdge, ScaleV( dPar), &p) ; GetPointFromCoord( p, pt) ; return true ; } //---------------------------------------------------------------------------- vr_bool vroniObject::GetBisectorSites( int nEdge, int& nOrigCrvL, int& nOrigSubCrvL, int& nOrigSubPntL, int& nOrigCrvR, int& nOrigSubCrvR, int& nOrigSubPntR) { int nSiteL, nSiteR ; t_site typeL, typeR ; // resetto valori passati in input nOrigCrvL = -1 ; nOrigSubCrvL = -1 ; nOrigSubPntL = -1 ; nOrigCrvR = -1 ; nOrigSubCrvR = -1 ; nOrigSubPntR = -1 ; // sito a sinistra GetLftSiteData( nEdge, &nSiteL, &typeL) ; if ( typeL == PNT) { nOrigCrvL = pnts[nSiteL].ext_appl.first ; nOrigSubPntL = pnts[nSiteL].ext_appl.second ; } else if ( typeL == SEG) { nOrigCrvL = segs[nSiteL].ext_appl.first ; nOrigSubCrvL = segs[nSiteL].ext_appl.second ; } else if ( typeL == ARC) { nOrigCrvL = arcs[nSiteL].ext_appl.first ; nOrigSubCrvL = arcs[nSiteL].ext_appl.second ; } // sito a destra GetRgtSiteData( nEdge, &nSiteR, &typeR) ; if ( typeR == PNT) { nOrigCrvR = pnts[nSiteR].ext_appl.first ; nOrigSubPntR = pnts[nSiteR].ext_appl.second ; } else if ( typeR == SEG) { nOrigCrvR = segs[nSiteR].ext_appl.first ; nOrigSubCrvR = segs[nSiteR].ext_appl.second ; } else if ( typeR == ARC) { nOrigCrvR = arcs[nSiteR].ext_appl.first ; nOrigSubCrvR = arcs[nSiteR].ext_appl.second ; } return true ; } //---------------------------------------------------------------------------- vr_bool vroniObject::GetApproxedBisectorParams( int nEdge, double& dParS, double& dParE) { // restituisce i parametri del bisettore approssimato, che potrebbe essere invertito // rispetto al bisettore originale salvato tra gli edges di vroni // se il bisettore non è quello approssimato nel buffer devo calcolarlo if ( nEdge != m_nBufferedVDEdge) { ResetVDBuffer() ; AddVDEdgeToBuffer( nEdge) ; m_nBufferedVDEdge = nEdge ; } // recupero i parametri dagli estremi dParS = UnscaleV( vde_buf[0].dPar1) ; dParE = UnscaleV( vde_buf[num_vde_buf-1].dPar2) ; return true ; } //---------------------------------------------------------------------------- int vroniObject::GetApproxedBisectorPointsNbr( int nEdge) { // se il bisettore non è quello approssimato nel buffer devo calcolarlo if ( nEdge != m_nBufferedVDEdge) { ResetVDBuffer() ; AddVDEdgeToBuffer( nEdge) ; m_nBufferedVDEdge = nEdge ; } return num_vde_buf + 1; } //---------------------------------------------------------------------------- vr_bool vroniObject::GetApproxedBisectorPoint( int nEdge, int nIdx, double pt[3], double& dPar) { // se il bisettore non è quello approssimato nel buffer devo calcolarlo if ( nEdge != m_nBufferedVDEdge) { ResetVDBuffer() ; AddVDEdgeToBuffer( nEdge) ; m_nBufferedVDEdge = nEdge ; } // verifico validità dell'indice passato int nPoints = GetApproxedBisectorPointsNbr( nEdge) ; if ( nIdx < 0 || nIdx >= nPoints) return false ; if ( nIdx == 0) { GetPointFromCoord( vde_buf[0].p1, pt) ; dPar = UnscaleV( vde_buf[0].dPar1) ; } else { GetPointFromCoord( vde_buf[nIdx-1].p2, pt) ; dPar = UnscaleV( vde_buf[nIdx-1].dPar2) ; } return true ; } //---------------------------------------------------------------------------- vr_bool vroniObject::GetLinearBisectorData( int nEdge, double ptS[3], double ptE[3], double& dParS, double& dParE) { // verifico sia effettivamente bisettore lineare if ( GetBisectorType( nEdge) != BisectorType::LINE) return false ; // calcolo i parametri GetEdgeParam( nEdge, &dParS, &dParE) ; dParS = UnscaleV( dParS) ; dParE = UnscaleV( dParE) ; // calcolo gli estremi coord coordS = GetNodeCoord( edges[nEdge].n1) ; GetPointFromCoord( coordS, ptS) ; coord coordE = GetNodeCoord( edges[nEdge].n2) ; GetPointFromCoord( coordE, ptE) ; return true ; } //---------------------------------------------------------------------------- vr_bool vroniObject::GetDegenerateHyperEllipticBisectorData( int nEdge, double ptS[3], double ptE[3], double ptC[3], double& dParS, double& dParE) { // verifico sia effettivamente del tipo corretto if ( GetBisectorType( nEdge) != BisectorType::DEGENERATE_HYPERELL) return false ; // calcolo il centro int i1, i2 ; t_site ltype, rtype ; GetLftSiteData( nEdge, &i1, <ype) ; GetRgtSiteData( nEdge, &i2, &rtype) ; coord p1 = ( ltype == PNT ? GetPntCoords( i1) : GetArcCenter( i1)) ; coord p2 = ( rtype == PNT ? GetPntCoords( i2) : GetArcCenter( i2)) ; coord p = MidPoint( p1, p2) ; GetPointFromCoord( p, ptC) ; // calcolo gli estremi coord coordS = GetNodeCoord( edges[nEdge].n1) ; GetPointFromCoord( coordS, ptS) ; coord coordE = GetNodeCoord( edges[nEdge].n2) ; GetPointFromCoord( coordE, ptE) ; // calcolo i parametri GetEdgeParam( nEdge, &dParS, &dParE) ; dParS = UnscaleV( dParS) ; dParE = UnscaleV( dParE) ; return true ; } //---------------------------------------------------------------------------- vr_bool vroniObject::IsRelatedEdge( int nEdge, int nOrigSite, bool bLeft) { // verifico se l'edge è relativo alla curva nOrigSite int nSiteL, nSiteR ; t_site nSiteTypeL, nSiteTypeR ; GetLftSiteData( nEdge, &nSiteL, &nSiteTypeL) ; GetRgtSiteData( nEdge, &nSiteR, &nSiteTypeR) ; if ( nSiteTypeL == UNKNOWN || nSiteTypeR == UNKNOWN || nSiteL == NIL || nSiteR == NIL) return false ; if ( ( nSiteTypeL == PNT && pnts[nSiteL].ext_appl.first == nOrigSite) || ( nSiteTypeL == SEG && segs[nSiteL].ext_appl.first == nOrigSite) || ( nSiteTypeL == ARC && arcs[nSiteL].ext_appl.first == nOrigSite) || ( nSiteTypeR == PNT && pnts[nSiteR].ext_appl.first == nOrigSite) || ( nSiteTypeR == SEG && segs[nSiteR].ext_appl.first == nOrigSite) || ( nSiteTypeR == ARC && arcs[nSiteR].ext_appl.first == nOrigSite)) { // verifico se è necessario calcolare active edges if ( num_active_edges == 0) { int nTmp ; InitializeEdgeData( false, bLeft, false, &nTmp) ; } // verifico è active ( e quindi dal lato richiesto di nOrigSite) for ( int j = 0 ; j < num_active_edges ; j ++) if ( active_edges[j] == nEdge) return true ; } return false ; } //---------------------------------------------------------------------------- vr_bool vroniObject::IsWMATEdge( int nEdge) { return edges[nEdge].w_mat.in_w_mat ; } //---------------------------------------------------------------------------- const char* vroniObject::GetExceptionMessage() { try { throw ; } catch ( const std::runtime_error& VRONIerror) { return VRONIerror.what() ; } catch (const std::exception& VRONIerror) { return VRONIerror.what() ; } catch ( ... ) { return "VRONI error: unknown type of error" ; } return "" ; } //---------------------------------------------------------------------------- void vroniObject::MyWriteVoronoiDiagram() { std::ofstream myfile ; myfile.open( "C:\\EgtData\\Varie\\Test.lua") ; // percorso del file // versione per scrivere i dati del diagramma su un file di testo // myfile << " EDGES DATA" << std::endl ; // for ( int i = 0 ; i < num_edges ; i ++) { // myfile << "Voronoi edge " << i << std::endl ; // myfile << " n1 = " << edges[i].n1 << std::endl ; // myfile << " n2 = " << edges[i].n2 << std::endl ; // myfile << " lft = " << edges[i].lft << std::endl ; // myfile << " rgt = " << edges[i].rgt << std::endl ; // myfile << " lft type = " << edges[i].ltype << std::endl ; // myfile << " rgt type = " << edges[i].rtype << std::endl ; // myfile << " s_ccw = " << edges[i].s_ccw << std::endl ; // myfile << " s_cw = " << edges[i].s_cw << std::endl ; // myfile << " e_ccw = " << edges[i].e_ccw << std::endl ; // myfile << " e_cw = " << edges[i].e_cw << std::endl ; // if (IsWmatEdge(i)) { // myfile << " wmat =" << edges[i].w_mat.in_w_mat << std::endl ; // // solo con Wmat // // myfile << " wmat rmin = " << UnscaleV( edges[i].w_mat.r_min) ; // // myfile << " wmat rmax = " << UnscaleV( edges[i].w_mat.r_max) ; // } // myfile.flush() ; // } // // myfile << std::endl << std::endl ; // myfile << "NODES DATA" << std::endl ; // for ( int i = 0 ; i < num_nodes ; i ++) { // myfile << "Voronoi node " << i << std::endl ; // auto p = GetNodeCoord(i) ; // myfile << " pt = " << UnscaleX(p.x) << ", " << UnscaleY(p.y) << std::endl ; // myfile << " r2 = " << UnscaleV( nodes[i].r2) << std::endl ; // myfile << " deg2 = " << nodes[i].deg2 << std::endl ; // myfile << " edge = " << nodes[i].edge << std::endl ; // myfile << " site = " << nodes[i].site << std::endl ; // } // versione per scrivere un file lua // N.B. i lati vengono rappresentati tutti con delle linee solo per avere le relazioni tra i nodi, non sono // rappresentativi dei veri lati del diagramma (parabole, ellissi, ...) // myfile << "-- Nodes " << num_nodes << std::endl ; myfile << "-- Edges " << num_edges << std::endl ; myfile << "local nId" << std::endl ; myfile << "local nGrp1 = EgtGroup( GDB_ID.ROOT)" << std::endl ; myfile << "local nGrp2 = EgtGroup( GDB_ID.ROOT)" << std::endl ; for ( int i = 0 ; i < num_nodes ; i ++) { double x1 = UnscaleX( nodes[i].p.x) ; double y1 = UnscaleY( nodes[i].p.y) ; myfile << "nId = EgtPoint( nGrp1, Point3d( " << x1 << ", " << y1 << ", 0))" << std::endl ; myfile << "EgtSetName( nId or GDB_ID.NULL, 'Node" << i << "')" << std::endl ; myfile.flush() ; } for ( int i = 0 ; i < num_edges ; i ++) { double x1 = UnscaleX( nodes[edges[i].n1].p.x) ; double y1 = UnscaleY( nodes[edges[i].n1].p.y) ; double x2 = UnscaleX( nodes[edges[i].n2].p.x) ; double y2 = UnscaleY( nodes[edges[i].n2].p.y) ; myfile << "nId = EgtLine( nGrp2, Point3d( " << x1 << ", " << y1 << ", 0), Point3d( " << x2 << ", " << y2 << ", 0))" << std::endl ; myfile << "EgtSetName( nId or GDB_ID.NULL, 'Edge" << i << "')" << std::endl ; myfile.flush() ; } myfile.close() ; return ; } //---------------------------------------------------------------------------- void vroniObject::MyFreeVDConstructionData() { FreeVDConstructionData() ; #ifdef RANDOM m_rnd_sites.clear() ; m_max_num_rnd_sites = 0; m_num_rnd_sites = 0; #endif } //---------------------------------------------------------------------------- void vroniObject::apiFreeOffsetData(void) { // libera la memoria utilizzata ( ResetOffsetData azzera i contatori ma non dealloca memoria) FreeOffsetData() ; // libero i dati degli edge utilizzati per il calcolo dell'offset FreeEdgeData() ; } //---------------------------------------------------------------------------- void vroniObject::apiFreeBisectorBuffer(void) { m_nBufferedVDEdge = -1 ; // libera la memoria utilizzata per approssimare il bisettore FreeDrawingBuffer() ; // libero i dati degli edge utilizzati per i calcoli FreeEdgeData() ; }