Estrusione sformata rispetto alla normale di superficie

Buonasera a tutti, mi chiedevo se solo io sento la mancanza di un comando che estrude una curva “normale” ad una superficie, ma con un angolo di sformo rispetto alla superficie stessa ?

Io attualmente uso un metodo un pò barbaro e dispendioso: estrudo una normale (azzurra), su quella creata, ne estrudo un’altra normale (blu), ricavo quella sformata (rossa) e infine elimino le prime 2…

Ciao e grazie

Chiesi una cosa del genere ai tempi del passaggio da Rhino 4 a Rhino 5… quindi, secoli fa! :laughing:
Il comando che tu menzioni non è altro che una “flangia” (su superficie), comando utile, presente nell’ormai defunto plug-in VSR.
Ricordo: estrudevi una curva, un bordo, e avevi la possibilità di definire una rotazione della superficie creata di un tot di angolo.

Sono passati decenni e ancora niente. Esiste soltanto il comando “Fin”… estrusione normale alla superficie, appunto.

Se può esserti utile ho fatto una definizione con GH che potrebbe essere anche uno script volendo…
Segue immagine di quello che fa e i componenti usati se uno deve ripetere con versioni precedenti a V7
In pratica in input hai una curva e una srf
decidi angolo e lunghezza estrusione e quantità di punti da campionare. Più punti più fedeltà alla curva proiettata.


Questa la definizione:
inclinata.gh (17,7 KB)

Ciao, forse potrebbe esserti utile questo plugin:

FinTools.rhp (35 KB)

Ciao! Un annetto fa o forse più chiesi la stessa cosa sul forum è il mitico Emilio mi sviluppò uno script in Python che puoi caricare da un edit di un icona di comando che ti posso garantire fa esattamente ciò che deve! Se cerchi nel forum mettendo come parole chiave “flangia” dovresti trovarlo facilmente.
Resta un appunto (se mi è concesso) alla mc neel di non provvedere ad aggiungere comandi e funzioni come questa (a mio modo di vedere importanti) nel programma (tanto più che utenti capaci e volenterosi riescono a risolvere con script il tutto.
Ps un altro comando che chiesi era l’analisi della deviazione tra superfici (non con la nuvola di punti) e anche qui Emilio e company risolsero il problema.

Ciao Marco.
Vero, me ne ero dimenticato … cosa che accade sempre più spesso. :grimacing:
Però mi pare che lo script non sia più disponibile, almeno io non riesco a scaricarlo.

Ciao gente :slight_smile:

Non mi ricordavo piu’ … :confused:

Ho dato un’occhiata al vecchio post … non e’ che fosse tutto chiaro,
anzi mi sembra ci fosse una confusione notevole.
Comunque cerchiamo di fregare Discourse: il vecchio script lo copio direttamente. :smile:

import rhinoscriptsyntax as rs
import scriptcontext
import Rhino
import math

def getdocdata( key, defval ):
  val = scriptcontext.doc.Strings.GetValue( key )
  if not val:
    val = defval
  return val

def setdocdata( key, val ):
  if val: 
    scriptcontext.doc.Strings.SetString( key, str( val ) )
  else:
    scriptcontext.doc.Strings.Delete( key )

def main():

  def getplane( pt ):
    '''
    reference plane at point
    '''
    ok, uu = cu.ClosestPoint( pt )
    if not ok:
      return None
    tan = cu.TangentAt( uu )
    ok, uu, vv = su.ClosestPoint( pt )
    if not ok:
      return None
    nrm = su.NormalAt( uu, vv )
    pla = Rhino.Geometry.Plane( pt, tan, nrm )
    return ( pla, nrm, tan )

  def addtemplines( pt ):
    '''
    draw reference lines
    '''
    gids = []
    plas = []
    pla, nrm, tan = getplane( pt )
    if not pla:
      return ( [], [] )
    vec = nrm * 1.0
    vec.Rotate( math.radians( degs * 1.0 ), tan )
    li = Rhino.Geometry.Line( pt, vec, leng )
    gid = scriptcontext.doc.Objects.AddLine( li )
    gids.append( gid )
    plas.append( pla )
    vec = nrm * -1.0
    vec.Rotate( math.radians( degs * 1.0 ), tan )
    li = Rhino.Geometry.Line( pt, vec, leng )
    gid = scriptcontext.doc.Objects.AddLine( li )
    gids.append( gid )
    plas.append( pla )
    vec = nrm * 1.0
    vec.Rotate( math.radians( degs * -1.0 ), tan )
    li = Rhino.Geometry.Line( pt, vec, leng )
    gid = scriptcontext.doc.Objects.AddLine( li )
    gids.append( gid )
    plas.append( pla )
    vec = nrm * -1.0
    vec.Rotate( math.radians( degs * -1.0 ), tan )
    li = Rhino.Geometry.Line( pt, vec, leng )
    gid = scriptcontext.doc.Objects.AddLine( li )
    gids.append( gid )
    plas.append( pla )
    return ( gids, plas )

  # get surface
  gob = Rhino.Input.Custom.GetObject()
  gob.AcceptNothing( True )
  gob.SetCommandPrompt( 'Surface ?' )
  gob.GeometryFilter = Rhino.DocObjects.ObjectType.Surface
  gob.Get()
  res = gob.Result()
  if res != Rhino.Input.GetResult.Object:
    return
  obref = gob.Object( 0 )
  su = obref.Surface()
  # get curve
  gob = Rhino.Input.Custom.GetObject()
  gob.SetCommandPrompt( 'Curve ?' )
  gob.AcceptNothing( True )
  gob.GeometryFilter = (
      Rhino.DocObjects.ObjectType.Curve |
      Rhino.DocObjects.ObjectType.EdgeFilter )
  gob.Get()
  res = gob.Result()
  if res != Rhino.Input.GetResult.Object:
    return
  obref = gob.Object( 0 )
  cu = obref.Curve()
  # get fin width
  deft = float( getdocdata( 'taperfin-leng', 10.0 ) )
  leng = rs.GetReal( 'Fin width ?', deft )
  if not leng:
    return
  setdocdata( 'taperfin-leng', leng )
  # get degrees
  deft = float( getdocdata( 'taperfin-degs', 15.0 ) )
  degs = rs.GetReal( 'Angle (Degrees) ?', deft )
  if degs is None:
    return
  setdocdata( 'taperfin-degs', degs )
  # get max point count for fin edge
  deft = int( getdocdata( 'taperfin-maxp', 0 ) )
  maxp = rs.GetInteger( 
      'Max point count to build fin edge (0 => no limit) ?', deft )
  if maxp is None:
    return
  setdocdata( 'taperfin-maxp', maxp )
  # get tolerance
  tolr = float( getdocdata( 'taperfin-tolr', 0.0 ) )
  tolr = rs.GetReal( 'Tolerance (0.0 => document tolerance) ?', deft )
  if tolr == 0.0:
    tolr = scriptcontext.doc.ModelAbsoluteTolerance
  if tolr is None:
    return
  setdocdata( 'taperfin-tolr', tolr )
  print( 'Tolerance = %g' % tolr )
  # draw lines to pick fin section
  dom = cu.Domain
  gids = []
  plas = []
  pt = cu.PointAtEnd
  gs, ps = addtemplines( pt )
  gids.extend( gs )
  plas.extend( ps )
  pt = cu.PointAt( dom.Mid )
  gs, ps = addtemplines( pt )
  gids.extend( gs )
  plas.extend( ps )
  pt = cu.PointAtStart
  gs, ps = addtemplines( pt )
  gids.extend( gs )
  plas.extend( ps )
  rs.UnselectAllObjects()
  scriptcontext.doc.Views.Redraw()
  # pick fin section
  tup = rs.GetObjectEx( 'Pick line for fin section', objects = gids )
  if not tup:
    rs.DeleteObjects( gids )
    return
  gid = tup[ 0 ]
  ix = gids.index( gid )
  refpla = plas[ ix ]
  reflin = Rhino.DocObjects.ObjRef( gid ).Curve() 
  rs.DeleteObjects( gids )
  # rebuild fin base curve
  pcnt = 10
  while True:
    recu = cu.Rebuild( pcnt, 3, True )
    ok, maxd, d1, d2, d3, d4, d5 = (
        Rhino.Geometry.Curve.GetDistancesBetweenCurves( cu, recu, tolr * 0.1 ) )
    if maxd < ( tolr * 0.5 ):
      break
    pcnt += 10
  print( 'Rebuilt curve with %d points' % pcnt )
  # get points for section lines
  if maxp and pcnt > maxp:
    pcnt = maxp
  uus = recu.DivideByCount( pcnt, True )
  if not uus:
    return
  pts = [ recu.PointAt( uu ) for uu in uus ]
  # build section lines
  tan0 = cu.TangentAtStart
  tan1 = cu.TangentAtEnd
  cu0, cu = cu, recu
  lins = []
  for pt in pts:
    pla, dum0, dum1 = getplane( pt )
    if not pla:
      print( 'Unable to get curve frame at point %s' % str( pt ) )
      return
    xfo = Rhino.Geometry.Transform.PlaneToPlane( refpla, pla )
    lin = reflin.DuplicateCurve()
    lin.Transform( xfo )
    lins.append( lin )
  cps = [ lin.PointAtEnd for lin in lins ]
  cu1 = Rhino.Geometry.Curve.CreateInterpolatedCurve( 
      cps, 3, Rhino.Geometry.CurveKnotStyle.Uniform, tan0, tan1 )
  breps = Rhino.Geometry.Brep.CreateFromLoft( 
      [ cu, cu1 ],
      Rhino.Geometry.Point3d.Unset,
      Rhino.Geometry.Point3d.Unset,
      Rhino.Geometry.LoftType.Normal,
      False )
  scriptcontext.doc.Objects.AddBrep( breps[ 0 ] )
  scriptcontext.doc.Views.Redraw()

main()

Occhio che c’era anche una definizione di Giuseppe, ma quella la lascio recuperare a voi … :grinning:

… Speri sia quello che cercavate.
Poi sul fatto che funzioni ho visto che c’erano parecchi dubbi gia’ allora …

4 Mi Piace

@emilio lo script funziona abbastanza bene… ho solo tolto la richiesta del numero di punti e della tolleranza per velocizzare il tutto…

Però c’è un però… Le isocurve non sono perpendicolari alla superficie ma risultano “stiracciate”…

Nelle foto si vede la superficie bianca creata con lo script, in confronto a quella rossa creata col mio metodo barbaro


Sicuramente è dovuto al fatto che le curve per creare la loft sono ricostruite con un numero di punti, e questo modo fa sì che i punti su ogni curva siano equidistanti tra loro…

Se ci fosse modo di sistemare questo problema lo script sarebbe perfetto…

Ciao

Ciao Thomas.

Non so se e quando riguardero’ lo script.
Ma credo che dividere la curva in tratti con curvatura abbastanza costante possa servire ad ottenere delle superfici migliori

Non per criticare, ma se per avere un buon risultato ci devo girare attorno, conviene che uso il mio solito metodo… che è un pò laborioso, ma mi restituisce superfici migliori…
Lo scopo era capire se è una cosa fattibile e se può servire a qualcun’altro… Logicamente se sono l’unico a cui serve, non ha senso sviluppare un comando solo per me…