//---------------------------------------------------------------------------- // EgalTech 20024 //---------------------------------------------------------------------------- // File : SbzFromCurves.cpp Data : 07.05.24 Versione : 2.6e2 // Contenuto : Implementazione di funzioni per creazione di superfici Sbz // a partire da curve, con diversi metodi. // // // Modifiche : 07.05.24 DB Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "GeoConst.h" #include "CurveLine.h" #include "CurveArc.h" #include "CurveComposite.h" #include "SurfTriMesh.h" #include "SurfBezier.h" #include "Voronoi.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EGkOffsetCurve.h" #include "/EgtDev/Include/EGkStmFromCurves.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" #include "/EgtDev/Include/EGkRotationMinimizingFrame.h" #include "/EgtDev/Include/EGkRotationXplaneFrame.h" #include "/EgtDev/Include/EGkIntersCurves.h" #include "/EgtDev/Include/EGkSurfBezier.h" #include "/EgtDev/Include/EGkSbzFromCurves.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include using namespace std ; //------------------------------------------------------------------------------- ISurfBezier* GetSurfBezierByFlatContour( const ICurve* pCurve, double dLinTol) { // verifica parametri if ( pCurve == nullptr) return nullptr ; // calcolo la polilinea che approssima la curva PolyLine PL ; if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) return nullptr ; // creo e setto la superficie trimesh PtrOwner pSbz( CreateBasicSurfBezier()) ; if ( IsNull( pSbz) || ! pSbz->CreateByFlatContour( PL)) return nullptr ; //// salvo tolleranza lineare usata //pSTM->SetLinearTolerance( dLinTol) ; // restituisco la superficie return Release( pSbz) ; } //------------------------------------------------------------------------------- ISurfBezier* GetSurfBezierByRegion( const CICURVEPVECTOR& vpCurve, double dLinTol) { // verifica parametri if ( &vpCurve == nullptr || vpCurve.empty()) return nullptr ; // calcolo le polilinee che approssimano le curve della regione POLYLINEVECTOR vPL ; Vector3d vtN ; if ( ! CalcRegionPolyLines( vpCurve, dLinTol, vPL, vtN)) return nullptr ; //for ( int i = 0 ; i < int(vpCurve.size()) ; ++i ) { // PolyLine pl ; // vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, pl) ; // vPL.push_back( pl) ; //} // creo e setto la superficie di bezier PtrOwner pSbz( CreateBasicSurfBezier()) ; if ( IsNull( pSbz) || ! pSbz->CreateByRegion( vPL)) return nullptr ; //// salvo tolleranza lineare usata //pSbz->SetLinearTolerance( dLinTol) ; // restituisco la superficie return Release( pSbz) ; } //------------------------------------------------------------------------------- ISurfBezier* GetSurfBezierByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr, bool bCapEnds, double dLinTol) { // verifica parametri if ( pCurve == nullptr || &vtExtr == nullptr) return nullptr ; // calcolo la polilinea che approssima la curva PolyLine PL ; if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) return nullptr ; //// se richiesta chiusura agli estremi //bool bDoCapEnds = false ; //if ( bCapEnds) { // // verifico che la curva sia chiusa e piatta // Plane3d plPlane ; // double dArea ; // if ( PL.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL)) { // // componente dell'estrusione perpendicolare al piano della curva // double dOrthoExtr = plPlane.GetVersN() * vtExtr ; // if ( ( abs( dOrthoExtr) > EPS_SMALL)) { // bDoCapEnds = true ; // // se negativa, inverto il senso del contorno // if ( dOrthoExtr < 0) // PL.Invert() ; // } // } //} PtrOwner pBezierForm( CurveToBezierCurve( pCurve)) ; // creo e setto la superficie trimesh PtrOwner pSbz( CreateBasicSurfBezier()) ; if ( IsNull( pSbz) || ! pSbz->CreateByExtrusion( pBezierForm, vtExtr)) return nullptr ; //// se da fare, metto i tappi sulle estremità //if ( bDoCapEnds) { // // creo la prima superficie di estremità // SurfTriMesh STM1 ; // if ( ! STM1.CreateByFlatContour( PL)) // return nullptr ; // // la copio // SurfTriMesh STM2 = STM1 ; // // inverto la prima superficie // STM1.Invert() ; // // traslo la seconda // STM2.Translate( vtExtr) ; // ////// SurfCompo? // //// le unisco alla superficie del fianco // //if ( ! pSbz->DoSewing( STM1) || ! pSTM->DoSewing( STM2)) // // return nullptr ; //} //// salvo tolleranza lineare usata //pSbz->SetLinearTolerance( dLinTol) ; // restituisco la superficie return Release( pSbz) ; } ////------------------------------------------------------------------------------- //ISurfCompo* //GetSurfBezierByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d& vtExtr, double dLinTol) ///// RICHIEDE LE SURF COMPO///////////////// //{ // // verifica parametri // if ( &vpCurve == nullptr || vpCurve.empty() || &vtExtr == nullptr) // return nullptr ; // // se una sola curva, uso la funzione precedente // if ( vpCurve.size() == 1 ) // return GetSurfBezierByExtrusion( vpCurve[0], vtExtr, true, dLinTol) ; // // calcolo le polilinee che approssimano le curve della regione // POLYLINEVECTOR vPL ; // Vector3d vtN ; // if ( ! CalcRegionPolyLines( vpCurve, dLinTol, vPL, vtN)) // return nullptr ; // // verifico la direzione di estrusione // double dOrthoExtr = vtN * vtExtr ; // if ( ( abs( dOrthoExtr) < EPS_SMALL)) // return nullptr ; // // se componente estrusione negativa, inverto tutti i percorsi // if ( dOrthoExtr < 0) { // for ( int i = 0 ; i < int( vPL.size()) ; ++ i) // vPL[i].Invert() ; // } // // creo la prima superficie di estremità // PtrOwner pSbz1( CreateBasicSurfBezier()) ; // if ( IsNull( pSbz1) || ! pSbz1->CreateByRegion( vPL)) // return nullptr ; // // creo la seconda superficie come copia della prima e poi inverto la prima // PtrOwner pSbz2( pSbz1->Clone()) ; // pSbz1->Invert() ; // // // creo e unisco le diverse superfici di estrusione // for ( int i = 0 ; i < int( vPL.size()) ; ++ i) { // // estrusione // SurfBezier SbzLat ; // if ( ! SbzLat.CreateByExtrusion( vPL[i], vtExtr)) // qui mi serve la curva e non la polyline della curva. vuol dire che dalla CalcRegionPolyLines devo farmi restituire anche le curve ordinate // return nullptr ; // } // //// salvo tolleranza lineare usata // //pSTM->SetLinearTolerance( dLinTol) ; // // restituisco la superficie // return Release( pSrfCompo) ; // in realtà dovrei restituire tre superfici!!! due basi e una sup laterale( e quindi fare una SurfCompo) oppure dovrei spezzare le basi in tot pezzi e creare una superficie unica //} //------------------------------------------------------------------------------- ISurfBezier* GetSurfBezierByRevolve( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx, bool bCapEnds, double dLinTol) // con l'aggiunta delle SURFCOMPO posso gestire anche i cap e curve che attraversano l'asse { // verifica parametri if ( pCurve == nullptr || &ptAx == nullptr || &vtAx == nullptr) return nullptr ; // limite minimo su tolleranza dLinTol = max( dLinTol, EPS_SMALL) ; //// calcolo la polilinea che approssima la curva //PolyLine PL ; //if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) // return nullptr ; //// calcolo lo step di rotazione //double dMaxRad = 0 ; //if ( ! PL.GetMaxDistanceFromLine( ptAx, vtAx, 1, dMaxRad, false) || dMaxRad < EPS_SMALL) // return nullptr ; //double dStepRotDeg = sqrt( 8 * dLinTol / dMaxRad) * RADTODEG ; //// se richiesta chiusura degli estremi //if ( bCapEnds && ! PL.IsClosed()) { // serve la SURFCOMPO // Vector3d vtAxN = vtAx ; // vtAxN.Normalize() ; // double dPosIni = 0, dPosFin = 0 ; // Point3d ptP ; // // proietto l'ultimo punto sull'asse di rotazione // if ( PL.GetLastPoint( ptP)) { // dPosFin = ( ptP - ptAx) * vtAxN ; // Point3d ptPOnAx = ptAx + dPosFin * vtAxN ; // // se non giace sull'asse, aggiungo il punto proiettato // if ( ! AreSamePointApprox( ptP, ptPOnAx)) { // double dU ; // PL.GetLastU( dU) ; // PL.AddUPoint( ( dU + 1), ptPOnAx) ; // } // } // // inverto la polilinea // PL.Invert() ; // // proietto l'ultimo punto (era il primo) sull'asse di rotazione // if ( PL.GetLastPoint( ptP)) { // dPosIni = ( ptP - ptAx) * vtAxN ; // Point3d ptPOnAx = ptAx + dPosIni * vtAxN ; // // se non giace sull'asse, aggiungo il punto proiettato // if ( ! AreSamePointApprox( ptP, ptPOnAx)) { // double dU ; // PL.GetLastU( dU) ; // PL.AddUPoint( ( dU + 1), ptPOnAx) ; // } // } // // decido se reinvertire la polilinea // if ( dPosFin > dPosIni) // PL.Invert() ; //} // creo e setto la superficie trimesh PtrOwner pSbz( CreateBasicSurfBezier()) ; if ( IsNull( pSbz) || ! pSbz->CreateByScrewing( pCurve, ptAx, vtAx, ANG_FULL, 0)) return nullptr ; // se superficie risultante chiusa, verifico che la normale sia verso l'esterno double dVol ; if ( pSbz->GetVolume( dVol) && dVol < 0) pSbz->Invert() ; //// salvo tolleranza lineare usata //pSbz->SetLinearTolerance( dLinTol) ; // restituisco la superficie return Release( pSbz) ; } //------------------------------------------------------------------------------- ISurfBezier* GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx, double dAngRotDeg, double dMove, bool bCapEnds, double dLinTol) { // verifica parametri if ( pCurve == nullptr || &ptAx == nullptr || &vtAx == nullptr) return nullptr ; // limite minimo su tolleranza dLinTol = max( dLinTol, EPS_SMALL) ; // calcolo la polilinea che approssima la curva PolyLine PL ; if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) return nullptr ; //// calcolo lo step di rotazione //double dMaxRad = 0 ; //if ( ! PL.GetMaxDistanceFromLine( ptAx, vtAx, 1, dMaxRad, false) || dMaxRad < EPS_SMALL) // return nullptr ; //double dStepRotDeg = sqrt( 8 * dLinTol / dMaxRad) * RADTODEG ; //// se superficie rototraslata, necessari limiti sulla lunghezza dei segmenti //if ( abs( dAngRotDeg) > EPS_ANG_SMALL && abs( dMove) > EPS_SMALL){ // double dLenMax = 2.5 * abs( dMove * dStepRotDeg / dAngRotDeg) ; // if ( ! PL.AdjustForMaxSegmentLen( dLenMax)) // return nullptr ; //} // creo e setto la superficie bezier PtrOwner pSbz( CreateBasicSurfBezier()) ; if ( IsNull( pSbz) || ! pSbz->CreateByScrewing( pCurve, ptAx, vtAx, dAngRotDeg, dMove)) return nullptr ; //// se richiesti caps /// richiede la SurfCompo //if ( bCapEnds) { // // determino se la sezione è chiusa e piatta // Plane3d plPlane ; double dArea ; // bool bSectClosedFlat = PL.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL) ; // // determino non sia una semplice rivoluzione // bool bRevolved = ( abs( abs( dAngRotDeg) - ANG_FULL) < EPS_ANG_SMALL && abs( dMove) < EPS_SMALL) ; // // se sezione chiusa e piatta e non rivoluzione, posso aggiungere i tappi // if ( bSectClosedFlat && ! bRevolved) { // // aggiungo il cap sull'inizio // PtrOwner pSci( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL)) // return nullptr ; // pSTM->DoSewing( *pSci) ; // // aggiungo il cap sulla fine // Vector3d vtMove = vtAx ; // vtMove.Normalize() ; // vtMove *= dMove ; // PL.Translate( vtMove) ; // PL.Rotate( ptAx, vtAx, dAngRotDeg) ; // PtrOwner pSce( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL)) // return nullptr ; // pSce->Invert() ; // pSTM->DoSewing( *pSce) ; // } //} // se superficie risultante chiusa, verifico che la normale sia verso l'esterno double dVol ; if ( pSbz->GetVolume( dVol) && dVol < 0) pSbz->Invert() ; //// salvo tolleranza lineare usata //pSTM->SetLinearTolerance( dLinTol) ; // restituisco la superficie return Release( pSbz) ; } // ////------------------------------------------------------------------------------- //static ISurfBezier* //GetSurfBezierSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide, int nCapType, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione////////////////////// //{ // // verifico che la linea guida sia piana // Plane3d plGuide ; // if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL)) // return nullptr ; // Vector3d vtNorm = plGuide.GetVersN() ; // // determino se la guida è chiusa // bool bGuideClosed = pGuide->IsClosed() ; // // curve di offset // OffsetCurve OffsCrvR ; // if ( ! OffsCrvR.Make( pGuide, dDimH / 2, ICurve::OFF_FILLET) || OffsCrvR.GetCurveCount() == 0) // return nullptr ; // PtrOwner pCrvR( OffsCrvR.GetLongerCurve()) ; // if ( IsNull( pCrvR)) // return nullptr ; // OffsetCurve OffsCrvL ; // if ( ! OffsCrvL.Make( pGuide, -dDimH / 2, ICurve::OFF_FILLET) || OffsCrvL.GetCurveCount() == 0) // return nullptr ; // PtrOwner pCrvL( OffsCrvL.GetLongerCurve()) ; // if ( IsNull( pCrvL)) // return nullptr ; // // costruisco le parti di superficie // PtrOwner pSrfTop( GetSurfTriMeshRuled( pCrvR, pCrvL, ISurfTriMesh::RLT_MINDIST, dLinTol)) ; // if ( IsNull( pSrfTop)) // return nullptr ; // PtrOwner pSrfBot( pSrfTop->Clone()) ; // if ( IsNull( pSrfBot)) // return nullptr ; // pSrfBot->Translate( -dDimV * vtNorm) ; // pSrfBot->Invert() ; // PtrOwner pSrfRgt( GetSurfTriMeshByExtrusion( pCrvR, -dDimV * vtNorm, false, dLinTol)) ; // if ( IsNull( pSrfRgt)) // return nullptr ; // pSrfRgt->Invert() ; // PtrOwner pSrfLft( GetSurfTriMeshByExtrusion( pCrvL, -dDimV * vtNorm, false, dLinTol)) ; // if ( IsNull( pSrfLft)) // return nullptr ; // // unisco le parti // PtrOwner pSTM( Release( pSrfTop)) ; // pSTM->DoSewing( *pSrfRgt) ; // pSTM->DoSewing( *pSrfLft) ; // pSTM->DoSewing( *pSrfBot) ; // // salvo tolleranza lineare usata e imposto angolo per smooth // pSTM->SetLinearTolerance( dLinTol) ; // pSTM->SetSmoothAngle( 20) ; // // se guida aperta e tappi piatti // if ( ! bGuideClosed && nCapType == RSCAP_FLAT) { // // verifico che le due estremità siano chiuse e piatte // POLYLINEVECTOR vPL ; // if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2) // return nullptr ; // Plane3d plEnds ; double dArea ; // if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL)) // return nullptr ; // if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL)) // return nullptr ; // // aggiungo il cap sull'inizio // PtrOwner pSci( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0])) // return nullptr ; // pSci->Invert() ; // pSTM->DoSewing( *pSci) ; // // aggiungo il cap sulla fine // PtrOwner pSce( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1])) // return nullptr ; // pSce->Invert() ; // pSTM->DoSewing( *pSce) ; // } // // se altrimenti guida aperta e tappi arrotondati // if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) { // // step di rotazione per rispettare la tolleranza // double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ; // // aggiungo il cap sull'inizio // Point3d ptStart ; // pGuide->GetStartPoint( ptStart) ; // Vector3d vtStart ; // pGuide->GetStartDir( vtStart) ; // vtStart.Rotate( vtNorm, 0, 1) ; // PolyLine PLStart ; // PLStart.AddUPoint( 0, ptStart) ; // PLStart.AddUPoint( 1, ptStart + dDimH / 2 * vtStart) ; // PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dDimV * vtNorm) ; // PLStart.AddUPoint( 3, ptStart - dDimV * vtNorm) ; // PtrOwner pSci( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0)) // return nullptr ; // pSci->Invert() ; // pSTM->DoSewing( *pSci) ; // // aggiungo il cap sulla fine // Point3d ptEnd ; // pGuide->GetEndPoint( ptEnd) ; // Vector3d vtEnd ; // pGuide->GetEndDir( vtEnd) ; // vtEnd.Rotate( vtNorm, 0, -1) ; // PolyLine PLEnd ; // PLEnd.AddUPoint( 0, ptEnd) ; // PLEnd.AddUPoint( 1, ptEnd + dDimH / 2 * vtEnd) ; // PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dDimV * vtNorm) ; // PLEnd.AddUPoint( 3, ptEnd - dDimV * vtNorm) ; // PtrOwner pSce( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0)) // return nullptr ; // pSce->Invert() ; // pSTM->DoSewing( *pSce) ; // } // // restituisco la superficie // return Release( pSTM) ; //} // ////------------------------------------------------------------------------------- //static ISurfBezier* //GetSurfBezierBeveledRectSwept( double dDimH, double dDimV, double dBevelH, double dBevelV, const ICurve* pGuide, int nCapType, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione////////////////////// //{ // // metodo di calcolo impostato da USE_VORONOI // // // verifico che la linea guida sia piana // Plane3d plGuide ; // if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL)) // return nullptr ; // // assegno la normale del piano // Vector3d vtNorm = plGuide.GetVersN() ; // // determino il punto centrale della sezione // Point3d ptCen ; // pGuide->GetStartPoint( ptCen) ; // ptCen -= dDimV / 2 * vtNorm ; // // determino se la guida è chiusa // bool bGuideClosed = pGuide->IsClosed() ; // // curve di offset // const int NUM_OFFS = 4 ; // OffsetCurve vOffsCrv[NUM_OFFS] ; // double vDist[NUM_OFFS] = { dDimH / 2 - dBevelH, -dDimH / 2 + dBevelH, dDimH / 2, -dDimH / 2} ; // bool bOk = true ; // if ( ! USE_VORONOI) { // future vRes[NUM_OFFS] ; // for ( int i = 0 ; i < NUM_OFFS ; ++ i) // vRes[i] = async( launch::async, &OffsetCurve::Make, &vOffsCrv[i], pGuide, vDist[i], ICurve::OFF_FILLET) ; // bool bOk = true ; // int nFin = 0 ; // while ( nFin < NUM_OFFS) { // for ( int i = 0 ; i < NUM_OFFS ; ++ i) { // if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) { // bOk = vRes[i].get() && bOk ; // ++ nFin ; // } // } // } // } // else { // // se Voronoi non è possibile calcolare gli offset di una stessa curva in parallelo // for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i) // bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ; // } // // if ( ! bOk || // vOffsCrv[0].GetCurveCount() == 0 || vOffsCrv[1].GetCurveCount() == 0 || // vOffsCrv[2].GetCurveCount() == 0 || vOffsCrv[3].GetCurveCount() == 0) // return nullptr ; // PtrOwner pCrvR( vOffsCrv[0].GetLongerCurve()) ; // if ( IsNull( pCrvR)) // return nullptr ; // PtrOwner pCrvL( vOffsCrv[1].GetLongerCurve()) ; // if ( IsNull( pCrvL)) // return nullptr ; // PtrOwner pCrvRb( vOffsCrv[2].GetLongerCurve()) ; // if ( IsNull( pCrvRb)) // return nullptr ; // pCrvRb->Translate( - dBevelV * vtNorm) ; // PtrOwner pCrvLb( vOffsCrv[3].GetLongerCurve()) ; // if ( IsNull( pCrvLb)) // return nullptr ; // pCrvLb->Translate( - dBevelV * vtNorm) ; // // costruisco le parti di superficie // PtrOwner pSrfTop( GetSurfTriMeshRuled( pCrvR, pCrvL, ISurfTriMesh::RLT_MINDIST, dLinTol)) ; // if ( IsNull( pSrfTop)) // return nullptr ; // PtrOwner pSrfBot( pSrfTop->Clone()) ; // if ( IsNull( pSrfBot)) // return nullptr ; // pSrfBot->Translate( -dDimV * vtNorm) ; // pSrfBot->Invert() ; // PtrOwner pSrfTopR( GetSurfTriMeshRuled( pCrvRb, pCrvR, ISurfTriMesh::RLT_MINDIST, dLinTol)) ; // if ( IsNull( pSrfTopR)) // return nullptr ; // PtrOwner pSrfBotR( pSrfTopR->Clone()) ; // if ( IsNull( pSrfBotR)) // return nullptr ; // pSrfBotR->Mirror( ptCen, vtNorm) ; // PtrOwner pSrfTopL( GetSurfTriMeshRuled( pCrvL, pCrvLb, ISurfTriMesh::RLT_MINDIST, dLinTol)) ; // if ( IsNull( pSrfTopL)) // return nullptr ; // PtrOwner pSrfBotL( pSrfTopL->Clone()) ; // if ( IsNull( pSrfBotL)) // return nullptr ; // pSrfBotL->Mirror( ptCen, vtNorm) ; // PtrOwner pSrfRgt( GetSurfTriMeshByExtrusion( pCrvRb, ( -dDimV + 2 * dBevelV) * vtNorm, false, dLinTol)) ; // if ( IsNull( pSrfRgt)) // return nullptr ; // pSrfRgt->Invert() ; // PtrOwner pSrfLft( GetSurfTriMeshByExtrusion( pCrvLb, ( -dDimV + 2 * dBevelV) * vtNorm, false, dLinTol)) ; // if ( IsNull( pSrfLft)) // return nullptr ; // // unisco le parti // int nBuckets = max( 4 * ( pSrfRgt->GetVertexSize() + pSrfLft->GetVertexSize()), 1000) ; // StmFromTriangleSoup stmSoup ; // if ( ! stmSoup.Start( nBuckets)) // return nullptr ; // stmSoup.AddSurfTriMesh( *pSrfTop) ; // stmSoup.AddSurfTriMesh( *pSrfTopR) ; // stmSoup.AddSurfTriMesh( *pSrfTopL) ; // stmSoup.AddSurfTriMesh( *pSrfRgt) ; // stmSoup.AddSurfTriMesh( *pSrfLft) ; // stmSoup.AddSurfTriMesh( *pSrfBotR) ; // stmSoup.AddSurfTriMesh( *pSrfBotL) ; // stmSoup.AddSurfTriMesh( *pSrfBot) ; // PtrOwner pSTM ; // // se guida aperta e tappi piatti // if ( ! bGuideClosed && nCapType == RSCAP_FLAT) { // // completo unione e recupero la superficie risultante // if ( ! stmSoup.End()) // return nullptr ; // pSTM.Set( stmSoup.GetSurf()) ; // // preparo seconda zuppa di triangoli per inserire i tappi // StmFromTriangleSoup stmCapSoup ; // if ( ! stmCapSoup.Start( nBuckets)) // return nullptr ; // // verifico che le due estremità siano chiuse e piatte // POLYLINEVECTOR vPL ; // if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2) // return nullptr ; // Plane3d plEnds ; double dArea ; // if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL)) // return nullptr ; // if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL)) // return nullptr ; // // calcolo il cap sull'inizio // PtrOwner pSci( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0])) // return nullptr ; // pSci->Invert() ; // // calcolo il cap sulla fine // PtrOwner pSce( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1])) // return nullptr ; // pSce->Invert() ; // // cucio i tappi all'estrusione // if ( ! pSTM->DoSewing( *pSci) || ! pSTM->DoSewing( *pSce)) // return nullptr ; // } // // se altrimenti guida aperta e tappi arrotondati // else if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) { // // step di rotazione per rispettare il tipo o la tolleranza // double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ; // // aggiungo il cap sull'inizio // Point3d ptStart ; // pGuide->GetStartPoint( ptStart) ; // Vector3d vtStart ; // pGuide->GetStartDir( vtStart) ; // vtStart.Rotate( vtNorm, 0, 1) ; // PolyLine PLStart ; // PLStart.AddUPoint( 0, ptStart) ; // PLStart.AddUPoint( 1, ptStart + ( dDimH / 2 - dBevelH) * vtStart) ; // PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dBevelV * vtNorm) ; // PLStart.AddUPoint( 3, ptStart + dDimH / 2 * vtStart - ( dDimV - dBevelV) * vtNorm) ; // PLStart.AddUPoint( 4, ptStart + ( dDimH / 2 - dBevelH) * vtStart - dDimV * vtNorm) ; // PLStart.AddUPoint( 5, ptStart - dDimV * vtNorm) ; // PtrOwner pSci( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0)) // return nullptr ; // pSci->Invert() ; // stmSoup.AddSurfTriMesh( *pSci) ; // // aggiungo il cap sulla fine // Point3d ptEnd ; // pGuide->GetEndPoint( ptEnd) ; // Vector3d vtEnd ; // pGuide->GetEndDir( vtEnd) ; // vtEnd.Rotate( vtNorm, 0, -1) ; // PolyLine PLEnd ; // PLEnd.AddUPoint( 0, ptEnd) ; // PLEnd.AddUPoint( 1, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd) ; // PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dBevelV * vtNorm) ; // PLEnd.AddUPoint( 3, ptEnd + dDimH / 2 * vtEnd - ( dDimV - dBevelV) * vtNorm) ; // PLEnd.AddUPoint( 4, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd - dDimV * vtNorm) ; // PLEnd.AddUPoint( 5, ptEnd - dDimV * vtNorm) ; // PtrOwner pSce( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0)) // return nullptr ; // pSce->Invert() ; // stmSoup.AddSurfTriMesh( *pSce) ; // // completo unione e recupero la superficie risultante // if ( ! stmSoup.End()) // return nullptr ; // pSTM.Set( stmSoup.GetSurf()) ; // } // else { // // completo unione e recupero la superficie risultante // if ( ! stmSoup.End()) // return nullptr ; // pSTM.Set( stmSoup.GetSurf()) ; // } // // salvo tolleranza lineare usata e imposto angolo per smooth // pSTM->SetLinearTolerance( dLinTol) ; // pSTM->SetSmoothAngle( 20) ; // // restituisco la superficie // return Release( pSTM) ; //} // ////------------------------------------------------------------------------------- //ISurfBezier* //GetSurfBezierRectSwept( double dDimH, double dDimV, double dBevelH, double dBevelV, const ICurve* pGuide, int nCapType, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione////////////////////// //{ // // verifica parametri // if ( pGuide == nullptr || dBevelH > 0.4 * dDimH || dBevelV > 0.4 * dDimV) // return nullptr ; // // determino se sezione squadrata o con smusso // bool bSharp = ( dBevelH < 100 * EPS_SMALL || dBevelV < 100 * EPS_SMALL) ; // // eseguo // if ( bSharp) // return GetSurfBezierSharpRectSwept( dDimH, dDimV, pGuide, nCapType, dLinTol) ; // else // return GetSurfBezierBeveledRectSwept( dDimH, dDimV, dBevelH, dBevelV, pGuide, nCapType, dLinTol) ; //} // ////------------------------------------------------------------------------------- //static ISurfBezier* //GetSurfBezierSweptInPlane( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtNorm, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione////////////////////// //{ // // determino se la sezione è chiusa // bool bSectClosed = pSect->IsClosed() ; // // determino se la guida è chiusa // bool bGuideClosed = pGuide->IsClosed() ; // // // riferimento all'inizio della linea guida // Frame3d frStart ; // Point3d ptStart ; // pGuide->GetStartPoint( ptStart) ; // Vector3d vtStart ; // pGuide->GetStartDir( vtStart) ; // frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ; // // // calcolo la polilinea che approssima la sezione // PolyLine PL ; // if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) // return nullptr ; // // // porto la sezione in questo riferimento e ve la appiattisco // if ( ! PL.ToLoc( frStart) || ! PL.Flatten()) // return nullptr ; // // // preparo collettore delle superfici componenti // StmFromTriangleSoup StmFts ; // if ( ! StmFts.Start()) // return nullptr ; // // // superficie swept // PtrOwner pPrevCrv ; // Point3d ptP ; // bool bPoint = PL.GetFirstPoint( ptP) ; // while ( bPoint) { // // nuova curva ( definita dall'Offset ) // OffsetCurve OffsCrv ; // if ( ! OffsCrv.Make( pGuide, ptP.x, ICurve::OFF_FILLET) || OffsCrv.GetCurveCount() == 0) // return nullptr ; // PtrOwner pCurrCrv( OffsCrv.GetLongerCurve()) ; // if ( IsNull( pCurrCrv)) // return nullptr ; // pCurrCrv->Translate( ptP.y * frStart.VersY()) ; // // se esiste la curva precedente, costruisco la rigata ( di tipo minima distanza) // if ( ! IsNull( pPrevCrv)) { // PtrOwner pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_MINDIST, dLinTol)) ; // if ( IsNull( pSr)) // return nullptr ; // // inserisco nel collettore // StmFts.AddSurfTriMesh( *pSr) ; // } // // salvo la curva come prossima precedente // pPrevCrv.Set( pCurrCrv) ; // // prossimo punto // bPoint = PL.GetNextPoint( ptP) ; // } // // // recupero la supeficie risultante // if ( ! StmFts.End()) // return nullptr ; // PtrOwner pSTM( GetBasicSurfTriMesh( StmFts.GetSurf())) ; // if ( IsNull( pSTM)) // return nullptr ; // // salvo tolleranza lineare usata // pSTM->SetLinearTolerance( dLinTol) ; // // // se richiesti caps e sezione chiusa e guida aperta // if ( bCapEnds && bSectClosed && ! bGuideClosed) { // // verifico che le due estremità siano chiuse e piatte // POLYLINEVECTOR vPL ; // if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2) // return nullptr ; // Plane3d plEnds ; double dArea ; // if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL)) // return nullptr ; // if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL)) // return nullptr ; // // aggiungo il cap sull'inizio // PtrOwner pSci( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL)) // return nullptr ; // pSci->ToGlob( frStart) ; // // unisco // pSTM->DoSewing( *pSci) ; // // riferimento alla fine della linea guida // Frame3d frEnd ; // Point3d ptEnd ; // pGuide->GetEndPoint( ptEnd) ; // Vector3d vtEnd ; // pGuide->GetEndDir( vtEnd) ; // frEnd.Set( ptEnd, -vtEnd, vtEnd ^ vtNorm) ; // // aggiungo il cap sulla fine // PtrOwner pSce( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL)) // return nullptr ; // pSce->Invert() ; // pSce->ToGlob( frEnd) ; // // unisco // pSTM->DoSewing( *pSce) ; // } // // se superficie risultante chiusa, verifico che la normale sia verso l'esterno // double dVol ; // if ( pSTM->GetVolume( dVol) && dVol < 0) // pSTM->Invert() ; // // restituisco la superficie // return Release( pSTM) ; //} // ////------------------------------------------------------------------------------- //static ISurfBezier* //GetSurfBezierSwept3d( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione////////////////////// //{ // // determino se la sezione è chiusa // bool bSectClosed = pSect->IsClosed() ; // // determino se la guida è chiusa // bool bGuideClosed = pGuide->IsClosed() ; // // determino algoritmo da usare per calcolare i riferimenti lungo la curva // bool bRMF = vtAx.IsSmall() ; // // // riferimento all'inizio della linea guida // Point3d ptStart ; // pGuide->GetStartPoint( ptStart) ; // Vector3d vtStart ; // pGuide->GetStartDir( vtStart) ; // Frame3d frStart ; // if ( bRMF) { // if ( ! frStart.Set( ptStart, vtStart)) // return nullptr ; // } // else { // Vector3d vtAxX = vtAx ^ vtStart ; // if ( vtAxX.IsSmall()) { // vtAxX = FromUprightOrtho( vtAx) ; // vtAxX.Rotate( vtAx, 0, 1) ; // } // if ( ! frStart.Set( ptStart, vtStart, vtAxX)) // return nullptr ; // } // // // calcolo la polilinea che approssima la sezione // PolyLine PL ; // if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) // return nullptr ; // // // recupero la sezione dalla PolyLine approssimata come Curva // PtrOwner pSecLocApprox( CreateBasicCurveComposite()) ; // if ( IsNull( pSecLocApprox) || // ! pSecLocApprox->FromPolyLine( PL) || // ! pSecLocApprox->IsValid()) // return nullptr ; // // // porto la PolyLine e la curva della sezione nel riferimento nel punto iniziale della guida // PL.ToLoc( frStart) ; // pSecLocApprox->ToLoc( frStart) ; // // // calcolo il vettore di Frames campionati lungo la guida mediante la tolleranza definita // FRAME3DVECTOR vFrames ; // if ( bRMF) { // RotationMinimizingFrame RMF ; // if ( ! RMF.Set( pGuide, frStart) || // ! RMF.GetFramesByTolerance( dLinTol, vFrames) || vFrames.empty()) // return nullptr ; // } // else { // RotationXplaneFrame RXF ; // if ( ! RXF.Set( pGuide, vtAx, frStart.VersX()) || // ! RXF.GetFramesByTolerance( dLinTol, vFrames) || vFrames.empty()) // return nullptr ; // } // // // preparo collettore delle superfici componenti // StmFromTriangleSoup StmFts ; // if ( ! StmFts.Start()) // return nullptr ; // // // per ogni Frame calcolato, la sezione va roto-traslata lungo la guida // for ( int i = 0 ; i < int( vFrames.size()) - 1 ; ++ i) { // // // definisco la sezione allo step corrente // PtrOwner pSecCurr( pSecLocApprox->Clone()) ; // if ( IsNull( pSecCurr) || ! pSecCurr->IsValid()) // return nullptr ; // // // considero la sezione ( in locale ) come vista dal globale // if ( ! pSecCurr->ToGlob( vFrames[i])) // return nullptr ; // // // definisco la sezione allo step successivo // PtrOwner pSecSucc( pSecLocApprox->Clone()) ; // if ( IsNull( pSecSucc) || ! pSecSucc->IsValid()) // return nullptr ; // // // considero la sezione ( in locale ) come vista dal globale // if ( ! pSecSucc->ToGlob( vFrames[i+1])) // return nullptr ; // // // creo la rigata tra queste due sezioni // PtrOwner pSr( GetSurfTriMeshRuled( pSecCurr, pSecSucc, ISurfTriMesh::RLT_ISOPAR_SMOOTH, dLinTol)) ; // if ( IsNull( pSr) || ! pSr->IsValid()) // return nullptr ; // // la inverto // pSr->Invert() ; // // inserisco la superficie nel collettore // StmFts.AddSurfTriMesh( *pSr) ; // } // // // se richiesti caps e sezione chiusa e guida aperta // if ( bCapEnds && bSectClosed && ! bGuideClosed) { // // // aggiungo il cap sull'inizio ( portandolo nel frame del punto iniziale della guida ) // PtrOwner pSci( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL)) // return nullptr ; // pSci->ToGlob( vFrames.front()) ; // // aggiungo // StmFts.AddSurfTriMesh( *pSci) ; // // // aggiungo il cap sulla fine ( portandolo nel frame del punto finale della guida ) // PtrOwner pSce( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL)) // return nullptr ; // pSce->ToGlob( vFrames.back()) ; // // inverto // pSce->Invert() ; // // aggiungo // StmFts.AddSurfTriMesh( *pSce) ; // } // // // recupero la supeficie risultante // if ( ! StmFts.End()) // return nullptr ; // PtrOwner pSTM( GetBasicSurfTriMesh( StmFts.GetSurf())) ; // if ( IsNull( pSTM)) // return nullptr ; // // salvo tolleranza lineare usata // pSTM->SetLinearTolerance( dLinTol) ; // // // se superficie risultante chiusa, verifico che la normale sia verso l'esterno // double dVol ; // if ( pSTM->GetVolume( dVol) && dVol < 0) // pSTM->Invert() ; // // // restituisco la superficie // return Release( pSTM) ; //} // ////------------------------------------------------------------------------------- //ISurfBezier* //GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx, // bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione////////////////////// //{ // // verifica parametri // if ( pSect == nullptr || pGuide == nullptr) // return nullptr ; // // bool bIsLine = false ; // if ( pGuide->GetType() == CRV_LINE) // bIsLine = true ; // else { // const CurveComposite* pCompo = GetBasicCurveComposite( pGuide) ; // Point3d ptStart, ptEnd ; // if ( pCompo != nullptr && pCompo->IsALine( 10 * EPS_SMALL, ptStart, ptEnd)) // bIsLine = true ; // } // // se la guida è piana // Plane3d plGuide ; // if ( pGuide->IsFlat( plGuide, bIsLine, 10 * EPS_SMALL)) // return GetSurfBezierSweptInPlane( pSect, pGuide, plGuide.GetVersN(), bCapEnds, dLinTol) ; // // // altrimenti swept 3d // return GetSurfBezierSwept3d( pSect, pGuide, vtAx, bCapEnds, dLinTol) ; //} // ////------------------------------------------------------------------------------- //ISurfBezier* //GetSurfBezierSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, const Vector3d& vtAx, // bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione////////////////////// //{ // // verifica dei parametri // if ( pSfrSect == nullptr || pGuide == nullptr) // return nullptr ; // // // predispongo collettore superfici componenti // StmFromTriangleSoup StmSoup ; // StmSoup.Start() ; // // // per ogni loop della superficie, creo una Swept // for ( int nC = 0 ; nC < pSfrSect->GetChunkCount() ; ++ nC) { // for ( int nL = 0 ; nL < pSfrSect->GetLoopCount( nC) ; ++ nL) { // // recupero il loop // PtrOwner pCrvLoop( pSfrSect->GetLoop( nC, nL)) ; // if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid()) // return nullptr ; // // creo la Trimesh Swept // PtrOwner pStmLoopSwept( GetSurfTriMeshSwept( pCrvLoop, pGuide, vtAx, false, dLinTol)) ; // if ( IsNull( pStmLoopSwept) || ! pStmLoopSwept->IsValid()) // return nullptr ; // // aggiungo la Swept ricavata al risultato finale ( come triangoli ) // StmSoup.AddSurfTriMesh( *pStmLoopSwept) ; // } // } // // // Recupero la superficie // if ( ! StmSoup.End()) // return nullptr ; // PtrOwner pStmSwept( StmSoup.GetSurf()) ; // if ( IsNull( pStmSwept)) // return nullptr ; // // // se rischiesta chiusura... // // Controllo solo che la guida non sia chiusa, la sezione derivando da una Flatregion è sempre chiusa // if ( bCapEnds && ! pGuide->IsClosed()) { // // recupero i loop all'inizio (dalla regione e apportunamente approssimati) // POLYLINEVECTOR vPLi ; // for ( int nC = 0 ; nC < pSfrSect->GetChunkCount() ; ++ nC) { // for ( int nL = 0 ; nL < pSfrSect->GetLoopCount( nC) ; ++ nL) { // vPLi.emplace_back() ; // if ( ! pSfrSect->ApproxLoopWithLines( nC, nL, dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPLi.back())) // return nullptr ; // } // } // // creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta) // PtrOwner pSci( CreateSurfTriMesh()) ; // if ( ! pSci->CreateByRegion( vPLi)) // return nullptr ; // pStmSwept->DoSewing( *pSci) ; // // recupero i loops alla fine // POLYLINEVECTOR vPLe ; // if ( ! pStmSwept->GetLoops( vPLe)) // return nullptr ; // // creo la superficie alla fine e la attacco // PtrOwner pSce( CreateSurfTriMesh()) ; // if ( ! pSce->CreateByRegion( vPLe)) // return nullptr ; // // attacco la superficie finale alla swept // pSce->Invert() ; // pStmSwept->DoSewing( *pSce) ; // } // // se superficie risultante chiusa, verifico che la normale sia verso l'esterno // double dVol ; // if ( pStmSwept->GetVolume( dVol) && dVol < 0) // pStmSwept->Invert() ; // // return Release( pStmSwept) ; //} // ////------------------------------------------------------------------------------- //ISurfBezier* //GetSurfBezierTransSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione////////////////////// //{ // // verifica parametri // if ( pSect == nullptr || pGuide == nullptr) // return nullptr ; // // determino se la sezione è chiusa // bool bSectClosed = pSect->IsClosed() ; // // punto iniziale della sezione e vettore a inizio guida // Point3d ptStart ; // if ( ! pSect->GetStartPoint( ptStart)) // return nullptr ; // Point3d ptGuide ; // if ( ! pGuide->GetStartPoint( ptGuide)) // return nullptr ; // Vector3d vtDelta = ptStart - ptGuide ; // // calcolo la polilinea che approssima la guida // PolyLine PLG ; // if ( ! pGuide->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PLG)) // return nullptr ; // // determino se la guida è chiusa // bool bGuideClosed = PLG.IsClosed() ; // // calcolo la superficie // PtrOwner pSTM( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSTM)) // return nullptr ; // // salvo tolleranza lineare usata // pSTM->SetLinearTolerance( dLinTol) ; // // superficie swept // PtrOwner pPrevCrv ; // Point3d ptP ; // bool bPoint = PLG.GetFirstPoint( ptP) ; // while ( bPoint) { // // nuova curva // PtrOwner pCurrCrv( pSect->Clone()) ; // if ( IsNull( pCurrCrv)) // return nullptr ; // pCurrCrv->Translate( ptP - ptStart + vtDelta) ; // // se esiste la curva precedente, costruisco la rigata (di tipo minima distanza) // if ( ! IsNull( pPrevCrv)) { // PtrOwner pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_ISOPAR, dLinTol)) ; // if ( IsNull( pSr)) // return nullptr ; // pSTM->DoSewing( *pSr) ; // } // // salvo la curva come prossima precedente // pPrevCrv.Set( pCurrCrv) ; // // prossimo punto // bPoint = PLG.GetNextPoint( ptP) ; // } // // se richiesti caps e sezione chiusa e guida aperta // if ( bCapEnds && bSectClosed && ! bGuideClosed) { // // calcolo la polilinea che approssima la sezione // PolyLine PLS ; // if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PLS)) // return nullptr ; // // verifico che la sezione sia chiusa e piatta // Plane3d plSect ; double dArea ; // if ( PLS.IsClosedAndFlat( plSect, dArea, 100 * EPS_SMALL)) { // // aggiungo il cap sull'inizio // PtrOwner pSci( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PLS)) // return nullptr ; // pSci->Invert() ; // Point3d ptGi ; PLG.GetFirstPoint( ptGi) ; // pSci->Translate( ptGi - ptStart + vtDelta) ; // pSTM->DoSewing( *pSci) ; // // aggiungo il cap sulla fine // PtrOwner pSce( CreateBasicSurfTriMesh()) ; // if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PLS)) // return nullptr ; // Point3d ptGe ; PLG.GetLastPoint( ptGe) ; // pSce->Translate( ptGe - ptStart + vtDelta) ; // pSTM->DoSewing( *pSce) ; // } // } // // se superficie risultante chiusa, verifico che la normale sia verso l'esterno // double dVol ; // if ( pSTM->GetVolume( dVol) && dVol < 0) // pSTM->Invert() ; // // restituisco la superficie // return Release( pSTM) ; //} //------------------------------------------------------------------------------- ISurfBezier* GetSurfBezierRuled( const Point3d& ptP, const ICurve* pCurve, double dLinTol) { // verifica parametri if ( &ptP == nullptr || pCurve == nullptr) return nullptr ; //// calcolo la polilinea che approssima la curva //PolyLine PL ; //if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) // return nullptr ; // creo e setto la superficie trimesh PtrOwner pSbz( CreateBasicSurfBezier()) ; if ( IsNull( pSbz) || ! pSbz->CreateByPointCurve( ptP, pCurve)) return nullptr ; //// salvo tolleranza lineare usata //pSbz->SetLinearTolerance( dLinTol) ; // restituisco la superficie return Release( pSbz) ; } //------------------------------------------------------------------------------- ISurfBezier* GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, double dLinTol) { // verifica parametri if ( pCurve1 == nullptr || pCurve2 == nullptr) return nullptr ; // dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier // se la curva è già una bezier singola la tengo, sennò la converto PtrOwner pCC1( CreateCurveComposite()) ; if ( pCurve1->GetType() != CRV_BEZIER) pCC1->AddCurve( CurveToBezierCurve( pCurve1)) ; else pCC1->AddCurve( pCurve1->Clone()) ; if ( IsNull( pCC1) || ! pCC1->IsValid()) return nullptr ; // se la curva è già una bezier singola la tengo, sennò la converto PtrOwner pCC2( CreateCurveComposite()) ; if ( pCurve2->GetType() != CRV_BEZIER) pCC2->AddCurve( CurveToBezierCurve( pCurve2)) ; else pCC2->AddCurve( pCurve2->Clone()) ; if ( IsNull( pCC2) || ! pCC2->IsValid()) return nullptr ; // creo e setto la superficie trimesh PtrOwner pSbz( CreateBasicSurfBezier()) ; if ( IsNull( pSbz) || ! pSbz->CreateByTwoCurves( pCC1, pCC2, nType)) return nullptr ; //// salvo tolleranza lineare usata //pSbz->SetLinearTolerance( dLinTol) ; // restituisco la superficie return Release( pSbz) ; } //------------------------------------------------------------------------------- ISurfBezier* GetSurfBezierSkinned( const CICURVEPVECTOR& vCrv, double dLinTol) { // verifico che le curve siano valide for ( int i = 0 ; i < int( vCrv.size()) ; ++i) { if( vCrv[i] == nullptr || ! vCrv[i]->IsValid()) return nullptr ; } // se ho solo due curve allora faccio la rigata if( vCrv.size() == 2) return GetSurfBezierRuled( vCrv[0], vCrv[1], ISurfBezier::RLT_B_MINDIST_PLUS, dLinTol) ; //trasformo le curve in curve di bezier, pareggio il numero di sottocurve e il grado // dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier // se la curva è già una bezier singola la tengo, sennò la converto ICURVEPOVECTOR vCrvBez ; for( int c = 0 ; c < int( vCrv.size()) ; ++c){ PtrOwner pCC( CreateCurveComposite()) ; if ( vCrv[c]->GetType() != CRV_BEZIER ) pCC->AddCurve( CurveToBezierCurve( vCrv[c])) ; else pCC->AddCurve( vCrv[c]->Clone()) ; if ( IsNull( pCC) || ! pCC->IsValid()) return nullptr ; vCrvBez.emplace_back( Release( pCC)) ; } // creo e setto la superficie trimesh PtrOwner pSbz( CreateBasicSurfBezier()) ; if ( IsNull( pSbz) || ! pSbz->CreateBySetOfCurves( vCrvBez)) return nullptr ; //// salvo tolleranza lineare usata //pSbz->SetLinearTolerance( dLinTol) ; // restituisco la superficie return Release( pSbz) ; }